base.h 101 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985
  1. // Formatting library for C++ - the base API for char/UTF-8
  2. //
  3. // Copyright (c) 2012 - present, Victor Zverovich
  4. // All rights reserved.
  5. //
  6. // For the license information refer to format.h.
  7. #ifndef FMT_BASE_H_
  8. #define FMT_BASE_H_
  9. #if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE)
  10. # define FMT_MODULE
  11. #endif
  12. #ifndef FMT_MODULE
  13. # include <limits.h> // CHAR_BIT
  14. # include <stdio.h> // FILE
  15. # include <string.h> // memcmp
  16. # include <type_traits> // std::enable_if
  17. #endif
  18. // The fmt library version in the form major * 10000 + minor * 100 + patch.
  19. #define FMT_VERSION 110105
  20. // Detect compiler versions.
  21. #if defined(__clang__) && !defined(__ibmxl__)
  22. # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
  23. #else
  24. # define FMT_CLANG_VERSION 0
  25. #endif
  26. #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
  27. # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
  28. #else
  29. # define FMT_GCC_VERSION 0
  30. #endif
  31. #if defined(__ICL)
  32. # define FMT_ICC_VERSION __ICL
  33. #elif defined(__INTEL_COMPILER)
  34. # define FMT_ICC_VERSION __INTEL_COMPILER
  35. #else
  36. # define FMT_ICC_VERSION 0
  37. #endif
  38. #if defined(_MSC_VER)
  39. # define FMT_MSC_VERSION _MSC_VER
  40. #else
  41. # define FMT_MSC_VERSION 0
  42. #endif
  43. // Detect standard library versions.
  44. #ifdef _GLIBCXX_RELEASE
  45. # define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE
  46. #else
  47. # define FMT_GLIBCXX_RELEASE 0
  48. #endif
  49. #ifdef _LIBCPP_VERSION
  50. # define FMT_LIBCPP_VERSION _LIBCPP_VERSION
  51. #else
  52. # define FMT_LIBCPP_VERSION 0
  53. #endif
  54. #ifdef _MSVC_LANG
  55. # define FMT_CPLUSPLUS _MSVC_LANG
  56. #else
  57. # define FMT_CPLUSPLUS __cplusplus
  58. #endif
  59. // Detect __has_*.
  60. #ifdef __has_feature
  61. # define FMT_HAS_FEATURE(x) __has_feature(x)
  62. #else
  63. # define FMT_HAS_FEATURE(x) 0
  64. #endif
  65. #ifdef __has_include
  66. # define FMT_HAS_INCLUDE(x) __has_include(x)
  67. #else
  68. # define FMT_HAS_INCLUDE(x) 0
  69. #endif
  70. #ifdef __has_builtin
  71. # define FMT_HAS_BUILTIN(x) __has_builtin(x)
  72. #else
  73. # define FMT_HAS_BUILTIN(x) 0
  74. #endif
  75. #ifdef __has_cpp_attribute
  76. # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
  77. #else
  78. # define FMT_HAS_CPP_ATTRIBUTE(x) 0
  79. #endif
  80. #define FMT_HAS_CPP14_ATTRIBUTE(attribute) \
  81. (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))
  82. #define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
  83. (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
  84. // Detect C++14 relaxed constexpr.
  85. #ifdef FMT_USE_CONSTEXPR
  86. // Use the provided definition.
  87. #elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L
  88. // GCC only allows constexpr member functions in non-literal types since 7.2:
  89. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297.
  90. # define FMT_USE_CONSTEXPR 1
  91. #elif FMT_ICC_VERSION
  92. # define FMT_USE_CONSTEXPR 0 // https://github.com/fmtlib/fmt/issues/1628
  93. #elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912
  94. # define FMT_USE_CONSTEXPR 1
  95. #else
  96. # define FMT_USE_CONSTEXPR 0
  97. #endif
  98. #if FMT_USE_CONSTEXPR
  99. # define FMT_CONSTEXPR constexpr
  100. #else
  101. # define FMT_CONSTEXPR
  102. #endif
  103. // Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated.
  104. #if !defined(__cpp_lib_is_constant_evaluated)
  105. # define FMT_USE_CONSTEVAL 0
  106. #elif FMT_CPLUSPLUS < 201709L
  107. # define FMT_USE_CONSTEVAL 0
  108. #elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10
  109. # define FMT_USE_CONSTEVAL 0
  110. #elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000
  111. # define FMT_USE_CONSTEVAL 0
  112. #elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L
  113. # define FMT_USE_CONSTEVAL 0 // consteval is broken in Apple clang < 14.
  114. #elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929
  115. # define FMT_USE_CONSTEVAL 0 // consteval is broken in MSVC VS2019 < 16.10.
  116. #elif defined(__cpp_consteval)
  117. # define FMT_USE_CONSTEVAL 1
  118. #elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101
  119. # define FMT_USE_CONSTEVAL 1
  120. #else
  121. # define FMT_USE_CONSTEVAL 0
  122. #endif
  123. #if FMT_USE_CONSTEVAL
  124. # define FMT_CONSTEVAL consteval
  125. # define FMT_CONSTEXPR20 constexpr
  126. #else
  127. # define FMT_CONSTEVAL
  128. # define FMT_CONSTEXPR20
  129. #endif
  130. // Check if exceptions are disabled.
  131. #ifdef FMT_USE_EXCEPTIONS
  132. // Use the provided definition.
  133. #elif defined(__GNUC__) && !defined(__EXCEPTIONS)
  134. # define FMT_USE_EXCEPTIONS 0
  135. #elif defined(__clang__) && !defined(__cpp_exceptions)
  136. # define FMT_USE_EXCEPTIONS 0
  137. #elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
  138. # define FMT_USE_EXCEPTIONS 0
  139. #else
  140. # define FMT_USE_EXCEPTIONS 1
  141. #endif
  142. #if FMT_USE_EXCEPTIONS
  143. # define FMT_TRY try
  144. # define FMT_CATCH(x) catch (x)
  145. #else
  146. # define FMT_TRY if (true)
  147. # define FMT_CATCH(x) if (false)
  148. #endif
  149. #ifdef FMT_NO_UNIQUE_ADDRESS
  150. // Use the provided definition.
  151. #elif FMT_CPLUSPLUS < 202002L
  152. // Not supported.
  153. #elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
  154. # define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
  155. // VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
  156. #elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
  157. # define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
  158. #endif
  159. #ifndef FMT_NO_UNIQUE_ADDRESS
  160. # define FMT_NO_UNIQUE_ADDRESS
  161. #endif
  162. #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
  163. # define FMT_FALLTHROUGH [[fallthrough]]
  164. #elif defined(__clang__)
  165. # define FMT_FALLTHROUGH [[clang::fallthrough]]
  166. #elif FMT_GCC_VERSION >= 700 && \
  167. (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
  168. # define FMT_FALLTHROUGH [[gnu::fallthrough]]
  169. #else
  170. # define FMT_FALLTHROUGH
  171. #endif
  172. // Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
  173. #if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__)
  174. # define FMT_NORETURN [[noreturn]]
  175. #else
  176. # define FMT_NORETURN
  177. #endif
  178. #ifdef FMT_NODISCARD
  179. // Use the provided definition.
  180. #elif FMT_HAS_CPP17_ATTRIBUTE(nodiscard)
  181. # define FMT_NODISCARD [[nodiscard]]
  182. #else
  183. # define FMT_NODISCARD
  184. #endif
  185. #ifdef FMT_DEPRECATED
  186. // Use the provided definition.
  187. #elif FMT_HAS_CPP14_ATTRIBUTE(deprecated)
  188. # define FMT_DEPRECATED [[deprecated]]
  189. #else
  190. # define FMT_DEPRECATED /* deprecated */
  191. #endif
  192. #if FMT_GCC_VERSION || FMT_CLANG_VERSION
  193. # define FMT_VISIBILITY(value) __attribute__((visibility(value)))
  194. #else
  195. # define FMT_VISIBILITY(value)
  196. #endif
  197. // Detect pragmas.
  198. #define FMT_PRAGMA_IMPL(x) _Pragma(#x)
  199. #if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER)
  200. // Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884
  201. // and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582.
  202. # define FMT_PRAGMA_GCC(x) FMT_PRAGMA_IMPL(GCC x)
  203. #else
  204. # define FMT_PRAGMA_GCC(x)
  205. #endif
  206. #if FMT_CLANG_VERSION
  207. # define FMT_PRAGMA_CLANG(x) FMT_PRAGMA_IMPL(clang x)
  208. #else
  209. # define FMT_PRAGMA_CLANG(x)
  210. #endif
  211. #if FMT_MSC_VERSION
  212. # define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
  213. #else
  214. # define FMT_MSC_WARNING(...)
  215. #endif
  216. // Enable minimal optimizations for more compact code in debug mode.
  217. FMT_PRAGMA_GCC(push_options)
  218. #if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
  219. FMT_PRAGMA_GCC(optimize("Og"))
  220. # define FMT_GCC_OPTIMIZED
  221. #endif
  222. FMT_PRAGMA_CLANG(diagnostic push)
  223. #ifdef FMT_ALWAYS_INLINE
  224. // Use the provided definition.
  225. #elif FMT_GCC_VERSION || FMT_CLANG_VERSION
  226. # define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
  227. #else
  228. # define FMT_ALWAYS_INLINE inline
  229. #endif
  230. // A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
  231. #if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED)
  232. # define FMT_INLINE FMT_ALWAYS_INLINE
  233. #else
  234. # define FMT_INLINE inline
  235. #endif
  236. #ifndef FMT_BEGIN_NAMESPACE
  237. # define FMT_BEGIN_NAMESPACE \
  238. namespace fmt { \
  239. inline namespace v11 {
  240. # define FMT_END_NAMESPACE \
  241. } \
  242. }
  243. #endif
  244. #ifndef FMT_EXPORT
  245. # define FMT_EXPORT
  246. # define FMT_BEGIN_EXPORT
  247. # define FMT_END_EXPORT
  248. #endif
  249. #ifdef _WIN32
  250. # define FMT_WIN32 1
  251. #else
  252. # define FMT_WIN32 0
  253. #endif
  254. #if !defined(FMT_HEADER_ONLY) && FMT_WIN32
  255. # if defined(FMT_LIB_EXPORT)
  256. # define FMT_API __declspec(dllexport)
  257. # elif defined(FMT_SHARED)
  258. # define FMT_API __declspec(dllimport)
  259. # endif
  260. #elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
  261. # define FMT_API FMT_VISIBILITY("default")
  262. #endif
  263. #ifndef FMT_API
  264. # define FMT_API
  265. #endif
  266. #ifndef FMT_OPTIMIZE_SIZE
  267. # define FMT_OPTIMIZE_SIZE 0
  268. #endif
  269. // FMT_BUILTIN_TYPE=0 may result in smaller library size at the cost of higher
  270. // per-call binary size by passing built-in types through the extension API.
  271. #ifndef FMT_BUILTIN_TYPES
  272. # define FMT_BUILTIN_TYPES 1
  273. #endif
  274. #define FMT_APPLY_VARIADIC(expr) \
  275. using unused = int[]; \
  276. (void)unused { 0, (expr, 0)... }
  277. FMT_BEGIN_NAMESPACE
  278. // Implementations of enable_if_t and other metafunctions for older systems.
  279. template <bool B, typename T = void>
  280. using enable_if_t = typename std::enable_if<B, T>::type;
  281. template <bool B, typename T, typename F>
  282. using conditional_t = typename std::conditional<B, T, F>::type;
  283. template <bool B> using bool_constant = std::integral_constant<bool, B>;
  284. template <typename T>
  285. using remove_reference_t = typename std::remove_reference<T>::type;
  286. template <typename T>
  287. using remove_const_t = typename std::remove_const<T>::type;
  288. template <typename T>
  289. using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
  290. template <typename T>
  291. using make_unsigned_t = typename std::make_unsigned<T>::type;
  292. template <typename T>
  293. using underlying_t = typename std::underlying_type<T>::type;
  294. template <typename T> using decay_t = typename std::decay<T>::type;
  295. using nullptr_t = decltype(nullptr);
  296. #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
  297. // A workaround for gcc 4.9 to make void_t work in a SFINAE context.
  298. template <typename...> struct void_t_impl {
  299. using type = void;
  300. };
  301. template <typename... T> using void_t = typename void_t_impl<T...>::type;
  302. #else
  303. template <typename...> using void_t = void;
  304. #endif
  305. struct monostate {
  306. constexpr monostate() {}
  307. };
  308. // An enable_if helper to be used in template parameters which results in much
  309. // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
  310. // to workaround a bug in MSVC 2019 (see #1140 and #1186).
  311. #ifdef FMT_DOC
  312. # define FMT_ENABLE_IF(...)
  313. #else
  314. # define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
  315. #endif
  316. template <typename T> constexpr auto min_of(T a, T b) -> T {
  317. return a < b ? a : b;
  318. }
  319. template <typename T> constexpr auto max_of(T a, T b) -> T {
  320. return a > b ? a : b;
  321. }
  322. namespace detail {
  323. // Suppresses "unused variable" warnings with the method described in
  324. // https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
  325. // (void)var does not work on many Intel compilers.
  326. template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}
  327. constexpr auto is_constant_evaluated(bool default_value = false) noexcept
  328. -> bool {
  329. // Workaround for incompatibility between clang 14 and libstdc++ consteval-based
  330. // std::is_constant_evaluated: https://github.com/fmtlib/fmt/issues/3247.
  331. #if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \
  332. (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500)
  333. ignore_unused(default_value);
  334. return __builtin_is_constant_evaluated();
  335. #elif defined(__cpp_lib_is_constant_evaluated)
  336. ignore_unused(default_value);
  337. return std::is_constant_evaluated();
  338. #else
  339. return default_value;
  340. #endif
  341. }
  342. // Suppresses "conditional expression is constant" warnings.
  343. template <typename T> FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T {
  344. return val;
  345. }
  346. FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
  347. const char* message);
  348. #if defined(FMT_ASSERT)
  349. // Use the provided definition.
  350. #elif defined(NDEBUG)
  351. // FMT_ASSERT is not empty to avoid -Wempty-body.
  352. # define FMT_ASSERT(condition, message) \
  353. fmt::detail::ignore_unused((condition), (message))
  354. #else
  355. # define FMT_ASSERT(condition, message) \
  356. ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
  357. ? (void)0 \
  358. : fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
  359. #endif
  360. #ifdef FMT_USE_INT128
  361. // Use the provided definition.
  362. #elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \
  363. !(FMT_CLANG_VERSION && FMT_MSC_VERSION)
  364. # define FMT_USE_INT128 1
  365. using int128_opt = __int128_t; // An optional native 128-bit integer.
  366. using uint128_opt = __uint128_t;
  367. inline auto map(int128_opt x) -> int128_opt { return x; }
  368. inline auto map(uint128_opt x) -> uint128_opt { return x; }
  369. #else
  370. # define FMT_USE_INT128 0
  371. #endif
  372. #if !FMT_USE_INT128
  373. enum class int128_opt {};
  374. enum class uint128_opt {};
  375. // Reduce template instantiations.
  376. inline auto map(int128_opt) -> monostate { return {}; }
  377. inline auto map(uint128_opt) -> monostate { return {}; }
  378. #endif
  379. #ifndef FMT_USE_BITINT
  380. # define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1500)
  381. #endif
  382. #if FMT_USE_BITINT
  383. FMT_PRAGMA_CLANG(diagnostic ignored "-Wbit-int-extension")
  384. template <int N> using bitint = _BitInt(N);
  385. template <int N> using ubitint = unsigned _BitInt(N);
  386. #else
  387. template <int N> struct bitint {};
  388. template <int N> struct ubitint {};
  389. #endif // FMT_USE_BITINT
  390. // Casts a nonnegative integer to unsigned.
  391. template <typename Int>
  392. FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {
  393. FMT_ASSERT(std::is_unsigned<Int>::value || value >= 0, "negative value");
  394. return static_cast<make_unsigned_t<Int>>(value);
  395. }
  396. template <typename Char>
  397. using unsigned_char = conditional_t<sizeof(Char) == 1, unsigned char, unsigned>;
  398. // A heuristic to detect std::string and std::[experimental::]string_view.
  399. // It is mainly used to avoid dependency on <[experimental/]string_view>.
  400. template <typename T, typename Enable = void>
  401. struct is_std_string_like : std::false_type {};
  402. template <typename T>
  403. struct is_std_string_like<T, void_t<decltype(std::declval<T>().find_first_of(
  404. typename T::value_type(), 0))>>
  405. : std::is_convertible<decltype(std::declval<T>().data()),
  406. const typename T::value_type*> {};
  407. // Check if the literal encoding is UTF-8.
  408. enum { is_utf8_enabled = "\u00A7"[1] == '\xA7' };
  409. enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };
  410. #ifndef FMT_UNICODE
  411. # define FMT_UNICODE 1
  412. #endif
  413. static_assert(!FMT_UNICODE || use_utf8,
  414. "Unicode support requires compiling with /utf-8");
  415. template <typename T> constexpr const char* narrow(const T*) { return nullptr; }
  416. constexpr FMT_ALWAYS_INLINE const char* narrow(const char* s) { return s; }
  417. template <typename Char>
  418. FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, std::size_t n)
  419. -> int {
  420. if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);
  421. for (; n != 0; ++s1, ++s2, --n) {
  422. if (*s1 < *s2) return -1;
  423. if (*s1 > *s2) return 1;
  424. }
  425. return 0;
  426. }
  427. namespace adl {
  428. using namespace std;
  429. template <typename Container>
  430. auto invoke_back_inserter()
  431. -> decltype(back_inserter(std::declval<Container&>()));
  432. } // namespace adl
  433. template <typename It, typename Enable = std::true_type>
  434. struct is_back_insert_iterator : std::false_type {};
  435. template <typename It>
  436. struct is_back_insert_iterator<
  437. It, bool_constant<std::is_same<
  438. decltype(adl::invoke_back_inserter<typename It::container_type>()),
  439. It>::value>> : std::true_type {};
  440. // Extracts a reference to the container from *insert_iterator.
  441. template <typename OutputIt>
  442. inline FMT_CONSTEXPR20 auto get_container(OutputIt it) ->
  443. typename OutputIt::container_type& {
  444. struct accessor : OutputIt {
  445. FMT_CONSTEXPR20 accessor(OutputIt base) : OutputIt(base) {}
  446. using OutputIt::container;
  447. };
  448. return *accessor(it).container;
  449. }
  450. } // namespace detail
  451. // Parsing-related public API and forward declarations.
  452. FMT_BEGIN_EXPORT
  453. /**
  454. * An implementation of `std::basic_string_view` for pre-C++17. It provides a
  455. * subset of the API. `fmt::basic_string_view` is used for format strings even
  456. * if `std::basic_string_view` is available to prevent issues when a library is
  457. * compiled with a different `-std` option than the client code (which is not
  458. * recommended).
  459. */
  460. template <typename Char> class basic_string_view {
  461. private:
  462. const Char* data_;
  463. size_t size_;
  464. public:
  465. using value_type = Char;
  466. using iterator = const Char*;
  467. constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
  468. /// Constructs a string reference object from a C string and a size.
  469. constexpr basic_string_view(const Char* s, size_t count) noexcept
  470. : data_(s), size_(count) {}
  471. constexpr basic_string_view(nullptr_t) = delete;
  472. /// Constructs a string reference object from a C string.
  473. #if FMT_GCC_VERSION
  474. FMT_ALWAYS_INLINE
  475. #endif
  476. FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
  477. #if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
  478. if (std::is_same<Char, char>::value) {
  479. size_ = __builtin_strlen(detail::narrow(s));
  480. return;
  481. }
  482. #endif
  483. size_t len = 0;
  484. while (*s++) ++len;
  485. size_ = len;
  486. }
  487. /// Constructs a string reference from a `std::basic_string` or a
  488. /// `std::basic_string_view` object.
  489. template <typename S,
  490. FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<
  491. typename S::value_type, Char>::value)>
  492. FMT_CONSTEXPR basic_string_view(const S& s) noexcept
  493. : data_(s.data()), size_(s.size()) {}
  494. /// Returns a pointer to the string data.
  495. constexpr auto data() const noexcept -> const Char* { return data_; }
  496. /// Returns the string size.
  497. constexpr auto size() const noexcept -> size_t { return size_; }
  498. constexpr auto begin() const noexcept -> iterator { return data_; }
  499. constexpr auto end() const noexcept -> iterator { return data_ + size_; }
  500. constexpr auto operator[](size_t pos) const noexcept -> const Char& {
  501. return data_[pos];
  502. }
  503. FMT_CONSTEXPR void remove_prefix(size_t n) noexcept {
  504. data_ += n;
  505. size_ -= n;
  506. }
  507. FMT_CONSTEXPR auto starts_with(basic_string_view<Char> sv) const noexcept
  508. -> bool {
  509. return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0;
  510. }
  511. FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool {
  512. return size_ >= 1 && *data_ == c;
  513. }
  514. FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool {
  515. return starts_with(basic_string_view<Char>(s));
  516. }
  517. // Lexicographically compare this string reference to other.
  518. FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
  519. int result =
  520. detail::compare(data_, other.data_, min_of(size_, other.size_));
  521. if (result != 0) return result;
  522. return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
  523. }
  524. FMT_CONSTEXPR friend auto operator==(basic_string_view lhs,
  525. basic_string_view rhs) -> bool {
  526. return lhs.compare(rhs) == 0;
  527. }
  528. friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
  529. return lhs.compare(rhs) != 0;
  530. }
  531. friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {
  532. return lhs.compare(rhs) < 0;
  533. }
  534. friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {
  535. return lhs.compare(rhs) <= 0;
  536. }
  537. friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {
  538. return lhs.compare(rhs) > 0;
  539. }
  540. friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {
  541. return lhs.compare(rhs) >= 0;
  542. }
  543. };
  544. using string_view = basic_string_view<char>;
  545. /// Specifies if `T` is an extended character type. Can be specialized by users.
  546. template <typename T> struct is_xchar : std::false_type {};
  547. template <> struct is_xchar<wchar_t> : std::true_type {};
  548. template <> struct is_xchar<char16_t> : std::true_type {};
  549. template <> struct is_xchar<char32_t> : std::true_type {};
  550. #ifdef __cpp_char8_t
  551. template <> struct is_xchar<char8_t> : std::true_type {};
  552. #endif
  553. // DEPRECATED! Will be replaced with an alias to prevent specializations.
  554. template <typename T> struct is_char : is_xchar<T> {};
  555. template <> struct is_char<char> : std::true_type {};
  556. template <typename T> class basic_appender;
  557. using appender = basic_appender<char>;
  558. // Checks whether T is a container with contiguous storage.
  559. template <typename T> struct is_contiguous : std::false_type {};
  560. class context;
  561. template <typename OutputIt, typename Char> class generic_context;
  562. template <typename Char> class parse_context;
  563. // Longer aliases for C++20 compatibility.
  564. template <typename Char> using basic_format_parse_context = parse_context<Char>;
  565. using format_parse_context = parse_context<char>;
  566. template <typename OutputIt, typename Char>
  567. using basic_format_context =
  568. conditional_t<std::is_same<OutputIt, appender>::value, context,
  569. generic_context<OutputIt, Char>>;
  570. using format_context = context;
  571. template <typename Char>
  572. using buffered_context =
  573. conditional_t<std::is_same<Char, char>::value, context,
  574. generic_context<basic_appender<Char>, Char>>;
  575. template <typename Context> class basic_format_arg;
  576. template <typename Context> class basic_format_args;
  577. // A separate type would result in shorter symbols but break ABI compatibility
  578. // between clang and gcc on ARM (#1919).
  579. using format_args = basic_format_args<context>;
  580. // A formatter for objects of type T.
  581. template <typename T, typename Char = char, typename Enable = void>
  582. struct formatter {
  583. // A deleted default constructor indicates a disabled formatter.
  584. formatter() = delete;
  585. };
  586. /// Reports a format error at compile time or, via a `format_error` exception,
  587. /// at runtime.
  588. // This function is intentionally not constexpr to give a compile-time error.
  589. FMT_NORETURN FMT_API void report_error(const char* message);
  590. enum class presentation_type : unsigned char {
  591. // Common specifiers:
  592. none = 0,
  593. debug = 1, // '?'
  594. string = 2, // 's' (string, bool)
  595. // Integral, bool and character specifiers:
  596. dec = 3, // 'd'
  597. hex, // 'x' or 'X'
  598. oct, // 'o'
  599. bin, // 'b' or 'B'
  600. chr, // 'c'
  601. // String and pointer specifiers:
  602. pointer = 3, // 'p'
  603. // Floating-point specifiers:
  604. exp = 1, // 'e' or 'E' (1 since there is no FP debug presentation)
  605. fixed, // 'f' or 'F'
  606. general, // 'g' or 'G'
  607. hexfloat // 'a' or 'A'
  608. };
  609. enum class align { none, left, right, center, numeric };
  610. enum class sign { none, minus, plus, space };
  611. enum class arg_id_kind { none, index, name };
  612. // Basic format specifiers for built-in and string types.
  613. class basic_specs {
  614. private:
  615. // Data is arranged as follows:
  616. //
  617. // 0 1 2 3
  618. // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  619. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  620. // |type |align| w | p | s |u|#|L| f | unused |
  621. // +-----+-----+---+---+---+-+-+-+-----+---------------------------+
  622. //
  623. // w - dynamic width info
  624. // p - dynamic precision info
  625. // s - sign
  626. // u - uppercase (e.g. 'X' for 'x')
  627. // # - alternate form ('#')
  628. // L - localized
  629. // f - fill size
  630. //
  631. // Bitfields are not used because of compiler bugs such as gcc bug 61414.
  632. enum : unsigned {
  633. type_mask = 0x00007,
  634. align_mask = 0x00038,
  635. width_mask = 0x000C0,
  636. precision_mask = 0x00300,
  637. sign_mask = 0x00C00,
  638. uppercase_mask = 0x01000,
  639. alternate_mask = 0x02000,
  640. localized_mask = 0x04000,
  641. fill_size_mask = 0x38000,
  642. align_shift = 3,
  643. width_shift = 6,
  644. precision_shift = 8,
  645. sign_shift = 10,
  646. fill_size_shift = 15,
  647. max_fill_size = 4
  648. };
  649. unsigned data_ = 1 << fill_size_shift;
  650. static_assert(sizeof(basic_specs::data_) * CHAR_BIT >= 18, "");
  651. // Character (code unit) type is erased to prevent template bloat.
  652. char fill_data_[max_fill_size] = {' '};
  653. FMT_CONSTEXPR void set_fill_size(size_t size) {
  654. data_ = (data_ & ~fill_size_mask) |
  655. (static_cast<unsigned>(size) << fill_size_shift);
  656. }
  657. public:
  658. constexpr auto type() const -> presentation_type {
  659. return static_cast<presentation_type>(data_ & type_mask);
  660. }
  661. FMT_CONSTEXPR void set_type(presentation_type t) {
  662. data_ = (data_ & ~type_mask) | static_cast<unsigned>(t);
  663. }
  664. constexpr auto align() const -> align {
  665. return static_cast<fmt::align>((data_ & align_mask) >> align_shift);
  666. }
  667. FMT_CONSTEXPR void set_align(fmt::align a) {
  668. data_ = (data_ & ~align_mask) | (static_cast<unsigned>(a) << align_shift);
  669. }
  670. constexpr auto dynamic_width() const -> arg_id_kind {
  671. return static_cast<arg_id_kind>((data_ & width_mask) >> width_shift);
  672. }
  673. FMT_CONSTEXPR void set_dynamic_width(arg_id_kind w) {
  674. data_ = (data_ & ~width_mask) | (static_cast<unsigned>(w) << width_shift);
  675. }
  676. FMT_CONSTEXPR auto dynamic_precision() const -> arg_id_kind {
  677. return static_cast<arg_id_kind>((data_ & precision_mask) >>
  678. precision_shift);
  679. }
  680. FMT_CONSTEXPR void set_dynamic_precision(arg_id_kind p) {
  681. data_ = (data_ & ~precision_mask) |
  682. (static_cast<unsigned>(p) << precision_shift);
  683. }
  684. constexpr bool dynamic() const {
  685. return (data_ & (width_mask | precision_mask)) != 0;
  686. }
  687. constexpr auto sign() const -> sign {
  688. return static_cast<fmt::sign>((data_ & sign_mask) >> sign_shift);
  689. }
  690. FMT_CONSTEXPR void set_sign(fmt::sign s) {
  691. data_ = (data_ & ~sign_mask) | (static_cast<unsigned>(s) << sign_shift);
  692. }
  693. constexpr auto upper() const -> bool { return (data_ & uppercase_mask) != 0; }
  694. FMT_CONSTEXPR void set_upper() { data_ |= uppercase_mask; }
  695. constexpr auto alt() const -> bool { return (data_ & alternate_mask) != 0; }
  696. FMT_CONSTEXPR void set_alt() { data_ |= alternate_mask; }
  697. FMT_CONSTEXPR void clear_alt() { data_ &= ~alternate_mask; }
  698. constexpr auto localized() const -> bool {
  699. return (data_ & localized_mask) != 0;
  700. }
  701. FMT_CONSTEXPR void set_localized() { data_ |= localized_mask; }
  702. constexpr auto fill_size() const -> size_t {
  703. return (data_ & fill_size_mask) >> fill_size_shift;
  704. }
  705. template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char>::value)>
  706. constexpr auto fill() const -> const Char* {
  707. return fill_data_;
  708. }
  709. template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
  710. constexpr auto fill() const -> const Char* {
  711. return nullptr;
  712. }
  713. template <typename Char> constexpr auto fill_unit() const -> Char {
  714. using uchar = unsigned char;
  715. return static_cast<Char>(static_cast<uchar>(fill_data_[0]) |
  716. (static_cast<uchar>(fill_data_[1]) << 8) |
  717. (static_cast<uchar>(fill_data_[2]) << 16));
  718. }
  719. FMT_CONSTEXPR void set_fill(char c) {
  720. fill_data_[0] = c;
  721. set_fill_size(1);
  722. }
  723. template <typename Char>
  724. FMT_CONSTEXPR void set_fill(basic_string_view<Char> s) {
  725. auto size = s.size();
  726. set_fill_size(size);
  727. if (size == 1) {
  728. unsigned uchar = static_cast<detail::unsigned_char<Char>>(s[0]);
  729. fill_data_[0] = static_cast<char>(uchar);
  730. fill_data_[1] = static_cast<char>(uchar >> 8);
  731. fill_data_[2] = static_cast<char>(uchar >> 16);
  732. return;
  733. }
  734. FMT_ASSERT(size <= max_fill_size, "invalid fill");
  735. for (size_t i = 0; i < size; ++i)
  736. fill_data_[i & 3] = static_cast<char>(s[i]);
  737. }
  738. FMT_CONSTEXPR void copy_fill_from(const basic_specs& specs) {
  739. set_fill_size(specs.fill_size());
  740. for (size_t i = 0; i < max_fill_size; ++i)
  741. fill_data_[i] = specs.fill_data_[i];
  742. }
  743. };
  744. // Format specifiers for built-in and string types.
  745. struct format_specs : basic_specs {
  746. int width;
  747. int precision;
  748. constexpr format_specs() : width(0), precision(-1) {}
  749. };
  750. /**
  751. * Parsing context consisting of a format string range being parsed and an
  752. * argument counter for automatic indexing.
  753. */
  754. template <typename Char = char> class parse_context {
  755. private:
  756. basic_string_view<Char> fmt_;
  757. int next_arg_id_;
  758. enum { use_constexpr_cast = !FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200 };
  759. FMT_CONSTEXPR void do_check_arg_id(int arg_id);
  760. public:
  761. using char_type = Char;
  762. using iterator = const Char*;
  763. constexpr explicit parse_context(basic_string_view<Char> fmt,
  764. int next_arg_id = 0)
  765. : fmt_(fmt), next_arg_id_(next_arg_id) {}
  766. /// Returns an iterator to the beginning of the format string range being
  767. /// parsed.
  768. constexpr auto begin() const noexcept -> iterator { return fmt_.begin(); }
  769. /// Returns an iterator past the end of the format string range being parsed.
  770. constexpr auto end() const noexcept -> iterator { return fmt_.end(); }
  771. /// Advances the begin iterator to `it`.
  772. FMT_CONSTEXPR void advance_to(iterator it) {
  773. fmt_.remove_prefix(detail::to_unsigned(it - begin()));
  774. }
  775. /// Reports an error if using the manual argument indexing; otherwise returns
  776. /// the next argument index and switches to the automatic indexing.
  777. FMT_CONSTEXPR auto next_arg_id() -> int {
  778. if (next_arg_id_ < 0) {
  779. report_error("cannot switch from manual to automatic argument indexing");
  780. return 0;
  781. }
  782. int id = next_arg_id_++;
  783. do_check_arg_id(id);
  784. return id;
  785. }
  786. /// Reports an error if using the automatic argument indexing; otherwise
  787. /// switches to the manual indexing.
  788. FMT_CONSTEXPR void check_arg_id(int id) {
  789. if (next_arg_id_ > 0) {
  790. report_error("cannot switch from automatic to manual argument indexing");
  791. return;
  792. }
  793. next_arg_id_ = -1;
  794. do_check_arg_id(id);
  795. }
  796. FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {
  797. next_arg_id_ = -1;
  798. }
  799. FMT_CONSTEXPR void check_dynamic_spec(int arg_id);
  800. };
  801. FMT_END_EXPORT
  802. namespace detail {
  803. // Constructs fmt::basic_string_view<Char> from types implicitly convertible
  804. // to it, deducing Char. Explicitly convertible types such as the ones returned
  805. // from FMT_STRING are intentionally excluded.
  806. template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
  807. constexpr auto to_string_view(const Char* s) -> basic_string_view<Char> {
  808. return s;
  809. }
  810. template <typename T, FMT_ENABLE_IF(is_std_string_like<T>::value)>
  811. constexpr auto to_string_view(const T& s)
  812. -> basic_string_view<typename T::value_type> {
  813. return s;
  814. }
  815. template <typename Char>
  816. constexpr auto to_string_view(basic_string_view<Char> s)
  817. -> basic_string_view<Char> {
  818. return s;
  819. }
  820. template <typename T, typename Enable = void>
  821. struct has_to_string_view : std::false_type {};
  822. // detail:: is intentional since to_string_view is not an extension point.
  823. template <typename T>
  824. struct has_to_string_view<
  825. T, void_t<decltype(detail::to_string_view(std::declval<T>()))>>
  826. : std::true_type {};
  827. /// String's character (code unit) type. detail:: is intentional to prevent ADL.
  828. template <typename S,
  829. typename V = decltype(detail::to_string_view(std::declval<S>()))>
  830. using char_t = typename V::value_type;
  831. enum class type {
  832. none_type,
  833. // Integer types should go first,
  834. int_type,
  835. uint_type,
  836. long_long_type,
  837. ulong_long_type,
  838. int128_type,
  839. uint128_type,
  840. bool_type,
  841. char_type,
  842. last_integer_type = char_type,
  843. // followed by floating-point types.
  844. float_type,
  845. double_type,
  846. long_double_type,
  847. last_numeric_type = long_double_type,
  848. cstring_type,
  849. string_type,
  850. pointer_type,
  851. custom_type
  852. };
  853. // Maps core type T to the corresponding type enum constant.
  854. template <typename T, typename Char>
  855. struct type_constant : std::integral_constant<type, type::custom_type> {};
  856. #define FMT_TYPE_CONSTANT(Type, constant) \
  857. template <typename Char> \
  858. struct type_constant<Type, Char> \
  859. : std::integral_constant<type, type::constant> {}
  860. FMT_TYPE_CONSTANT(int, int_type);
  861. FMT_TYPE_CONSTANT(unsigned, uint_type);
  862. FMT_TYPE_CONSTANT(long long, long_long_type);
  863. FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
  864. FMT_TYPE_CONSTANT(int128_opt, int128_type);
  865. FMT_TYPE_CONSTANT(uint128_opt, uint128_type);
  866. FMT_TYPE_CONSTANT(bool, bool_type);
  867. FMT_TYPE_CONSTANT(Char, char_type);
  868. FMT_TYPE_CONSTANT(float, float_type);
  869. FMT_TYPE_CONSTANT(double, double_type);
  870. FMT_TYPE_CONSTANT(long double, long_double_type);
  871. FMT_TYPE_CONSTANT(const Char*, cstring_type);
  872. FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);
  873. FMT_TYPE_CONSTANT(const void*, pointer_type);
  874. constexpr auto is_integral_type(type t) -> bool {
  875. return t > type::none_type && t <= type::last_integer_type;
  876. }
  877. constexpr auto is_arithmetic_type(type t) -> bool {
  878. return t > type::none_type && t <= type::last_numeric_type;
  879. }
  880. constexpr auto set(type rhs) -> int { return 1 << static_cast<int>(rhs); }
  881. constexpr auto in(type t, int set) -> bool {
  882. return ((set >> static_cast<int>(t)) & 1) != 0;
  883. }
  884. // Bitsets of types.
  885. enum {
  886. sint_set =
  887. set(type::int_type) | set(type::long_long_type) | set(type::int128_type),
  888. uint_set = set(type::uint_type) | set(type::ulong_long_type) |
  889. set(type::uint128_type),
  890. bool_set = set(type::bool_type),
  891. char_set = set(type::char_type),
  892. float_set = set(type::float_type) | set(type::double_type) |
  893. set(type::long_double_type),
  894. string_set = set(type::string_type),
  895. cstring_set = set(type::cstring_type),
  896. pointer_set = set(type::pointer_type)
  897. };
  898. struct view {};
  899. template <typename Char, typename T> struct named_arg;
  900. template <typename T> struct is_named_arg : std::false_type {};
  901. template <typename T> struct is_static_named_arg : std::false_type {};
  902. template <typename Char, typename T>
  903. struct is_named_arg<named_arg<Char, T>> : std::true_type {};
  904. template <typename Char, typename T> struct named_arg : view {
  905. const Char* name;
  906. const T& value;
  907. named_arg(const Char* n, const T& v) : name(n), value(v) {}
  908. static_assert(!is_named_arg<T>::value, "nested named arguments");
  909. };
  910. template <bool B = false> constexpr auto count() -> int { return B ? 1 : 0; }
  911. template <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {
  912. return (B1 ? 1 : 0) + count<B2, Tail...>();
  913. }
  914. template <typename... Args> constexpr auto count_named_args() -> int {
  915. return count<is_named_arg<Args>::value...>();
  916. }
  917. template <typename... Args> constexpr auto count_static_named_args() -> int {
  918. return count<is_static_named_arg<Args>::value...>();
  919. }
  920. template <typename Char> struct named_arg_info {
  921. const Char* name;
  922. int id;
  923. };
  924. // named_args is non-const to suppress a bogus -Wmaybe-uninitalized in gcc 13.
  925. template <typename Char>
  926. FMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,
  927. int named_arg_index,
  928. basic_string_view<Char> arg_name) {
  929. for (int i = 0; i < named_arg_index; ++i) {
  930. if (named_args[i].name == arg_name) report_error("duplicate named arg");
  931. }
  932. }
  933. template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
  934. void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
  935. ++arg_index;
  936. }
  937. template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
  938. void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
  939. int& named_arg_index, const T& arg) {
  940. check_for_duplicate<Char>(named_args, named_arg_index, arg.name);
  941. named_args[named_arg_index++] = {arg.name, arg_index++};
  942. }
  943. template <typename T, typename Char,
  944. FMT_ENABLE_IF(!is_static_named_arg<T>::value)>
  945. FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>*, int& arg_index,
  946. int&) {
  947. ++arg_index;
  948. }
  949. template <typename T, typename Char,
  950. FMT_ENABLE_IF(is_static_named_arg<T>::value)>
  951. FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
  952. int& arg_index, int& named_arg_index) {
  953. check_for_duplicate<Char>(named_args, named_arg_index, T::name);
  954. named_args[named_arg_index++] = {T::name, arg_index++};
  955. }
  956. // To minimize the number of types we need to deal with, long is translated
  957. // either to int or to long long depending on its size.
  958. enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES };
  959. using long_type = conditional_t<long_short, int, long long>;
  960. using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
  961. template <typename T>
  962. using format_as_result =
  963. remove_cvref_t<decltype(format_as(std::declval<const T&>()))>;
  964. template <typename T>
  965. using format_as_member_result =
  966. remove_cvref_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>;
  967. template <typename T, typename Enable = std::true_type>
  968. struct use_format_as : std::false_type {};
  969. // format_as member is only used to avoid injection into the std namespace.
  970. template <typename T, typename Enable = std::true_type>
  971. struct use_format_as_member : std::false_type {};
  972. // Only map owning types because mapping views can be unsafe.
  973. template <typename T>
  974. struct use_format_as<
  975. T, bool_constant<std::is_arithmetic<format_as_result<T>>::value>>
  976. : std::true_type {};
  977. template <typename T>
  978. struct use_format_as_member<
  979. T, bool_constant<std::is_arithmetic<format_as_member_result<T>>::value>>
  980. : std::true_type {};
  981. template <typename T, typename U = remove_const_t<T>>
  982. using use_formatter =
  983. bool_constant<(std::is_class<T>::value || std::is_enum<T>::value ||
  984. std::is_union<T>::value || std::is_array<T>::value) &&
  985. !has_to_string_view<T>::value && !is_named_arg<T>::value &&
  986. !use_format_as<T>::value && !use_format_as_member<U>::value>;
  987. template <typename Char, typename T, typename U = remove_const_t<T>>
  988. auto has_formatter_impl(T* p, buffered_context<Char>* ctx = nullptr)
  989. -> decltype(formatter<U, Char>().format(*p, *ctx), std::true_type());
  990. template <typename Char> auto has_formatter_impl(...) -> std::false_type;
  991. // T can be const-qualified to check if it is const-formattable.
  992. template <typename T, typename Char> constexpr auto has_formatter() -> bool {
  993. return decltype(has_formatter_impl<Char>(static_cast<T*>(nullptr)))::value;
  994. }
  995. // Maps formatting argument types to natively supported types or user-defined
  996. // types with formatters. Returns void on errors to be SFINAE-friendly.
  997. template <typename Char> struct type_mapper {
  998. static auto map(signed char) -> int;
  999. static auto map(unsigned char) -> unsigned;
  1000. static auto map(short) -> int;
  1001. static auto map(unsigned short) -> unsigned;
  1002. static auto map(int) -> int;
  1003. static auto map(unsigned) -> unsigned;
  1004. static auto map(long) -> long_type;
  1005. static auto map(unsigned long) -> ulong_type;
  1006. static auto map(long long) -> long long;
  1007. static auto map(unsigned long long) -> unsigned long long;
  1008. static auto map(int128_opt) -> int128_opt;
  1009. static auto map(uint128_opt) -> uint128_opt;
  1010. static auto map(bool) -> bool;
  1011. template <int N>
  1012. static auto map(bitint<N>) -> conditional_t<N <= 64, long long, void>;
  1013. template <int N>
  1014. static auto map(ubitint<N>)
  1015. -> conditional_t<N <= 64, unsigned long long, void>;
  1016. template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
  1017. static auto map(T) -> conditional_t<
  1018. std::is_same<T, char>::value || std::is_same<T, Char>::value, Char, void>;
  1019. static auto map(float) -> float;
  1020. static auto map(double) -> double;
  1021. static auto map(long double) -> long double;
  1022. static auto map(Char*) -> const Char*;
  1023. static auto map(const Char*) -> const Char*;
  1024. template <typename T, typename C = char_t<T>,
  1025. FMT_ENABLE_IF(!std::is_pointer<T>::value)>
  1026. static auto map(const T&) -> conditional_t<std::is_same<C, Char>::value,
  1027. basic_string_view<C>, void>;
  1028. static auto map(void*) -> const void*;
  1029. static auto map(const void*) -> const void*;
  1030. static auto map(volatile void*) -> const void*;
  1031. static auto map(const volatile void*) -> const void*;
  1032. static auto map(nullptr_t) -> const void*;
  1033. template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
  1034. std::is_member_pointer<T>::value)>
  1035. static auto map(const T&) -> void;
  1036. template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
  1037. static auto map(const T& x) -> decltype(map(format_as(x)));
  1038. template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>
  1039. static auto map(const T& x) -> decltype(map(formatter<T>::format_as(x)));
  1040. template <typename T, FMT_ENABLE_IF(use_formatter<T>::value)>
  1041. static auto map(T&) -> conditional_t<has_formatter<T, Char>(), T&, void>;
  1042. template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
  1043. static auto map(const T& named_arg) -> decltype(map(named_arg.value));
  1044. };
  1045. // detail:: is used to workaround a bug in MSVC 2017.
  1046. template <typename T, typename Char>
  1047. using mapped_t = decltype(detail::type_mapper<Char>::map(std::declval<T&>()));
  1048. // A type constant after applying type_mapper.
  1049. template <typename T, typename Char = char>
  1050. using mapped_type_constant = type_constant<mapped_t<T, Char>, Char>;
  1051. template <typename T, typename Context,
  1052. type TYPE =
  1053. mapped_type_constant<T, typename Context::char_type>::value>
  1054. using stored_type_constant = std::integral_constant<
  1055. type, Context::builtin_types || TYPE == type::int_type ? TYPE
  1056. : type::custom_type>;
  1057. // A parse context with extra data used only in compile-time checks.
  1058. template <typename Char>
  1059. class compile_parse_context : public parse_context<Char> {
  1060. private:
  1061. int num_args_;
  1062. const type* types_;
  1063. using base = parse_context<Char>;
  1064. public:
  1065. FMT_CONSTEXPR explicit compile_parse_context(basic_string_view<Char> fmt,
  1066. int num_args, const type* types,
  1067. int next_arg_id = 0)
  1068. : base(fmt, next_arg_id), num_args_(num_args), types_(types) {}
  1069. constexpr auto num_args() const -> int { return num_args_; }
  1070. constexpr auto arg_type(int id) const -> type { return types_[id]; }
  1071. FMT_CONSTEXPR auto next_arg_id() -> int {
  1072. int id = base::next_arg_id();
  1073. if (id >= num_args_) report_error("argument not found");
  1074. return id;
  1075. }
  1076. FMT_CONSTEXPR void check_arg_id(int id) {
  1077. base::check_arg_id(id);
  1078. if (id >= num_args_) report_error("argument not found");
  1079. }
  1080. using base::check_arg_id;
  1081. FMT_CONSTEXPR void check_dynamic_spec(int arg_id) {
  1082. ignore_unused(arg_id);
  1083. if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id]))
  1084. report_error("width/precision is not integer");
  1085. }
  1086. };
  1087. // An argument reference.
  1088. template <typename Char> union arg_ref {
  1089. FMT_CONSTEXPR arg_ref(int idx = 0) : index(idx) {}
  1090. FMT_CONSTEXPR arg_ref(basic_string_view<Char> n) : name(n) {}
  1091. int index;
  1092. basic_string_view<Char> name;
  1093. };
  1094. // Format specifiers with width and precision resolved at formatting rather
  1095. // than parsing time to allow reusing the same parsed specifiers with
  1096. // different sets of arguments (precompilation of format strings).
  1097. template <typename Char = char> struct dynamic_format_specs : format_specs {
  1098. arg_ref<Char> width_ref;
  1099. arg_ref<Char> precision_ref;
  1100. };
  1101. // Converts a character to ASCII. Returns '\0' on conversion failure.
  1102. template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
  1103. constexpr auto to_ascii(Char c) -> char {
  1104. return c <= 0xff ? static_cast<char>(c) : '\0';
  1105. }
  1106. // Returns the number of code units in a code point or 1 on error.
  1107. template <typename Char>
  1108. FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int {
  1109. if (const_check(sizeof(Char) != 1)) return 1;
  1110. auto c = static_cast<unsigned char>(*begin);
  1111. return static_cast<int>((0x3a55000000000000ull >> (2 * (c >> 3))) & 3) + 1;
  1112. }
  1113. // Parses the range [begin, end) as an unsigned integer. This function assumes
  1114. // that the range is non-empty and the first character is a digit.
  1115. template <typename Char>
  1116. FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
  1117. int error_value) noexcept -> int {
  1118. FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
  1119. unsigned value = 0, prev = 0;
  1120. auto p = begin;
  1121. do {
  1122. prev = value;
  1123. value = value * 10 + unsigned(*p - '0');
  1124. ++p;
  1125. } while (p != end && '0' <= *p && *p <= '9');
  1126. auto num_digits = p - begin;
  1127. begin = p;
  1128. int digits10 = static_cast<int>(sizeof(int) * CHAR_BIT * 3 / 10);
  1129. if (num_digits <= digits10) return static_cast<int>(value);
  1130. // Check for overflow.
  1131. unsigned max = INT_MAX;
  1132. return num_digits == digits10 + 1 &&
  1133. prev * 10ull + unsigned(p[-1] - '0') <= max
  1134. ? static_cast<int>(value)
  1135. : error_value;
  1136. }
  1137. FMT_CONSTEXPR inline auto parse_align(char c) -> align {
  1138. switch (c) {
  1139. case '<': return align::left;
  1140. case '>': return align::right;
  1141. case '^': return align::center;
  1142. }
  1143. return align::none;
  1144. }
  1145. template <typename Char> constexpr auto is_name_start(Char c) -> bool {
  1146. return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_';
  1147. }
  1148. template <typename Char, typename Handler>
  1149. FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end,
  1150. Handler&& handler) -> const Char* {
  1151. Char c = *begin;
  1152. if (c >= '0' && c <= '9') {
  1153. int index = 0;
  1154. if (c != '0')
  1155. index = parse_nonnegative_int(begin, end, INT_MAX);
  1156. else
  1157. ++begin;
  1158. if (begin == end || (*begin != '}' && *begin != ':'))
  1159. report_error("invalid format string");
  1160. else
  1161. handler.on_index(index);
  1162. return begin;
  1163. }
  1164. if (FMT_OPTIMIZE_SIZE > 1 || !is_name_start(c)) {
  1165. report_error("invalid format string");
  1166. return begin;
  1167. }
  1168. auto it = begin;
  1169. do {
  1170. ++it;
  1171. } while (it != end && (is_name_start(*it) || ('0' <= *it && *it <= '9')));
  1172. handler.on_name({begin, to_unsigned(it - begin)});
  1173. return it;
  1174. }
  1175. template <typename Char> struct dynamic_spec_handler {
  1176. parse_context<Char>& ctx;
  1177. arg_ref<Char>& ref;
  1178. arg_id_kind& kind;
  1179. FMT_CONSTEXPR void on_index(int id) {
  1180. ref = id;
  1181. kind = arg_id_kind::index;
  1182. ctx.check_arg_id(id);
  1183. ctx.check_dynamic_spec(id);
  1184. }
  1185. FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
  1186. ref = id;
  1187. kind = arg_id_kind::name;
  1188. ctx.check_arg_id(id);
  1189. }
  1190. };
  1191. template <typename Char> struct parse_dynamic_spec_result {
  1192. const Char* end;
  1193. arg_id_kind kind;
  1194. };
  1195. // Parses integer | "{" [arg_id] "}".
  1196. template <typename Char>
  1197. FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
  1198. int& value, arg_ref<Char>& ref,
  1199. parse_context<Char>& ctx)
  1200. -> parse_dynamic_spec_result<Char> {
  1201. FMT_ASSERT(begin != end, "");
  1202. auto kind = arg_id_kind::none;
  1203. if ('0' <= *begin && *begin <= '9') {
  1204. int val = parse_nonnegative_int(begin, end, -1);
  1205. if (val == -1) report_error("number is too big");
  1206. value = val;
  1207. } else {
  1208. if (*begin == '{') {
  1209. ++begin;
  1210. if (begin != end) {
  1211. Char c = *begin;
  1212. if (c == '}' || c == ':') {
  1213. int id = ctx.next_arg_id();
  1214. ref = id;
  1215. kind = arg_id_kind::index;
  1216. ctx.check_dynamic_spec(id);
  1217. } else {
  1218. begin = parse_arg_id(begin, end,
  1219. dynamic_spec_handler<Char>{ctx, ref, kind});
  1220. }
  1221. }
  1222. if (begin != end && *begin == '}') return {++begin, kind};
  1223. }
  1224. report_error("invalid format string");
  1225. }
  1226. return {begin, kind};
  1227. }
  1228. template <typename Char>
  1229. FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,
  1230. format_specs& specs, arg_ref<Char>& width_ref,
  1231. parse_context<Char>& ctx) -> const Char* {
  1232. auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);
  1233. specs.set_dynamic_width(result.kind);
  1234. return result.end;
  1235. }
  1236. template <typename Char>
  1237. FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
  1238. format_specs& specs,
  1239. arg_ref<Char>& precision_ref,
  1240. parse_context<Char>& ctx) -> const Char* {
  1241. ++begin;
  1242. if (begin == end) {
  1243. report_error("invalid precision");
  1244. return begin;
  1245. }
  1246. auto result =
  1247. parse_dynamic_spec(begin, end, specs.precision, precision_ref, ctx);
  1248. specs.set_dynamic_precision(result.kind);
  1249. return result.end;
  1250. }
  1251. enum class state { start, align, sign, hash, zero, width, precision, locale };
  1252. // Parses standard format specifiers.
  1253. template <typename Char>
  1254. FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
  1255. dynamic_format_specs<Char>& specs,
  1256. parse_context<Char>& ctx, type arg_type)
  1257. -> const Char* {
  1258. auto c = '\0';
  1259. if (end - begin > 1) {
  1260. auto next = to_ascii(begin[1]);
  1261. c = parse_align(next) == align::none ? to_ascii(*begin) : '\0';
  1262. } else {
  1263. if (begin == end) return begin;
  1264. c = to_ascii(*begin);
  1265. }
  1266. struct {
  1267. state current_state = state::start;
  1268. FMT_CONSTEXPR void operator()(state s, bool valid = true) {
  1269. if (current_state >= s || !valid)
  1270. report_error("invalid format specifier");
  1271. current_state = s;
  1272. }
  1273. } enter_state;
  1274. using pres = presentation_type;
  1275. constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
  1276. struct {
  1277. const Char*& begin;
  1278. format_specs& specs;
  1279. type arg_type;
  1280. FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* {
  1281. if (!in(arg_type, set)) report_error("invalid format specifier");
  1282. specs.set_type(pres_type);
  1283. return begin + 1;
  1284. }
  1285. } parse_presentation_type{begin, specs, arg_type};
  1286. for (;;) {
  1287. switch (c) {
  1288. case '<':
  1289. case '>':
  1290. case '^':
  1291. enter_state(state::align);
  1292. specs.set_align(parse_align(c));
  1293. ++begin;
  1294. break;
  1295. case '+':
  1296. case ' ':
  1297. specs.set_sign(c == ' ' ? sign::space : sign::plus);
  1298. FMT_FALLTHROUGH;
  1299. case '-':
  1300. enter_state(state::sign, in(arg_type, sint_set | float_set));
  1301. ++begin;
  1302. break;
  1303. case '#':
  1304. enter_state(state::hash, is_arithmetic_type(arg_type));
  1305. specs.set_alt();
  1306. ++begin;
  1307. break;
  1308. case '0':
  1309. enter_state(state::zero);
  1310. if (!is_arithmetic_type(arg_type))
  1311. report_error("format specifier requires numeric argument");
  1312. if (specs.align() == align::none) {
  1313. // Ignore 0 if align is specified for compatibility with std::format.
  1314. specs.set_align(align::numeric);
  1315. specs.set_fill('0');
  1316. }
  1317. ++begin;
  1318. break;
  1319. // clang-format off
  1320. case '1': case '2': case '3': case '4': case '5':
  1321. case '6': case '7': case '8': case '9': case '{':
  1322. // clang-format on
  1323. enter_state(state::width);
  1324. begin = parse_width(begin, end, specs, specs.width_ref, ctx);
  1325. break;
  1326. case '.':
  1327. enter_state(state::precision,
  1328. in(arg_type, float_set | string_set | cstring_set));
  1329. begin = parse_precision(begin, end, specs, specs.precision_ref, ctx);
  1330. break;
  1331. case 'L':
  1332. enter_state(state::locale, is_arithmetic_type(arg_type));
  1333. specs.set_localized();
  1334. ++begin;
  1335. break;
  1336. case 'd': return parse_presentation_type(pres::dec, integral_set);
  1337. case 'X': specs.set_upper(); FMT_FALLTHROUGH;
  1338. case 'x': return parse_presentation_type(pres::hex, integral_set);
  1339. case 'o': return parse_presentation_type(pres::oct, integral_set);
  1340. case 'B': specs.set_upper(); FMT_FALLTHROUGH;
  1341. case 'b': return parse_presentation_type(pres::bin, integral_set);
  1342. case 'E': specs.set_upper(); FMT_FALLTHROUGH;
  1343. case 'e': return parse_presentation_type(pres::exp, float_set);
  1344. case 'F': specs.set_upper(); FMT_FALLTHROUGH;
  1345. case 'f': return parse_presentation_type(pres::fixed, float_set);
  1346. case 'G': specs.set_upper(); FMT_FALLTHROUGH;
  1347. case 'g': return parse_presentation_type(pres::general, float_set);
  1348. case 'A': specs.set_upper(); FMT_FALLTHROUGH;
  1349. case 'a': return parse_presentation_type(pres::hexfloat, float_set);
  1350. case 'c':
  1351. if (arg_type == type::bool_type) report_error("invalid format specifier");
  1352. return parse_presentation_type(pres::chr, integral_set);
  1353. case 's':
  1354. return parse_presentation_type(pres::string,
  1355. bool_set | string_set | cstring_set);
  1356. case 'p':
  1357. return parse_presentation_type(pres::pointer, pointer_set | cstring_set);
  1358. case '?':
  1359. return parse_presentation_type(pres::debug,
  1360. char_set | string_set | cstring_set);
  1361. case '}': return begin;
  1362. default: {
  1363. if (*begin == '}') return begin;
  1364. // Parse fill and alignment.
  1365. auto fill_end = begin + code_point_length(begin);
  1366. if (end - fill_end <= 0) {
  1367. report_error("invalid format specifier");
  1368. return begin;
  1369. }
  1370. if (*begin == '{') {
  1371. report_error("invalid fill character '{'");
  1372. return begin;
  1373. }
  1374. auto alignment = parse_align(to_ascii(*fill_end));
  1375. enter_state(state::align, alignment != align::none);
  1376. specs.set_fill(
  1377. basic_string_view<Char>(begin, to_unsigned(fill_end - begin)));
  1378. specs.set_align(alignment);
  1379. begin = fill_end + 1;
  1380. }
  1381. }
  1382. if (begin == end) return begin;
  1383. c = to_ascii(*begin);
  1384. }
  1385. }
  1386. template <typename Char, typename Handler>
  1387. FMT_CONSTEXPR FMT_INLINE auto parse_replacement_field(const Char* begin,
  1388. const Char* end,
  1389. Handler&& handler)
  1390. -> const Char* {
  1391. ++begin;
  1392. if (begin == end) {
  1393. handler.on_error("invalid format string");
  1394. return end;
  1395. }
  1396. int arg_id = 0;
  1397. switch (*begin) {
  1398. case '}':
  1399. handler.on_replacement_field(handler.on_arg_id(), begin);
  1400. return begin + 1;
  1401. case '{': handler.on_text(begin, begin + 1); return begin + 1;
  1402. case ':': arg_id = handler.on_arg_id(); break;
  1403. default: {
  1404. struct id_adapter {
  1405. Handler& handler;
  1406. int arg_id;
  1407. FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); }
  1408. FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
  1409. arg_id = handler.on_arg_id(id);
  1410. }
  1411. } adapter = {handler, 0};
  1412. begin = parse_arg_id(begin, end, adapter);
  1413. arg_id = adapter.arg_id;
  1414. Char c = begin != end ? *begin : Char();
  1415. if (c == '}') {
  1416. handler.on_replacement_field(arg_id, begin);
  1417. return begin + 1;
  1418. }
  1419. if (c != ':') {
  1420. handler.on_error("missing '}' in format string");
  1421. return end;
  1422. }
  1423. break;
  1424. }
  1425. }
  1426. begin = handler.on_format_specs(arg_id, begin + 1, end);
  1427. if (begin == end || *begin != '}')
  1428. return handler.on_error("unknown format specifier"), end;
  1429. return begin + 1;
  1430. }
  1431. template <typename Char, typename Handler>
  1432. FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> fmt,
  1433. Handler&& handler) {
  1434. auto begin = fmt.data(), end = begin + fmt.size();
  1435. auto p = begin;
  1436. while (p != end) {
  1437. auto c = *p++;
  1438. if (c == '{') {
  1439. handler.on_text(begin, p - 1);
  1440. begin = p = parse_replacement_field(p - 1, end, handler);
  1441. } else if (c == '}') {
  1442. if (p == end || *p != '}')
  1443. return handler.on_error("unmatched '}' in format string");
  1444. handler.on_text(begin, p);
  1445. begin = ++p;
  1446. }
  1447. }
  1448. handler.on_text(begin, end);
  1449. }
  1450. // Checks char specs and returns true iff the presentation type is char-like.
  1451. FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool {
  1452. auto type = specs.type();
  1453. if (type != presentation_type::none && type != presentation_type::chr &&
  1454. type != presentation_type::debug) {
  1455. return false;
  1456. }
  1457. if (specs.align() == align::numeric || specs.sign() != sign::none ||
  1458. specs.alt()) {
  1459. report_error("invalid format specifier for char");
  1460. }
  1461. return true;
  1462. }
  1463. // A base class for compile-time strings.
  1464. struct compile_string {};
  1465. template <typename T, typename Char>
  1466. FMT_VISIBILITY("hidden") // Suppress an ld warning on macOS (#3769).
  1467. FMT_CONSTEXPR auto invoke_parse(parse_context<Char>& ctx) -> const Char* {
  1468. using mapped_type = remove_cvref_t<mapped_t<T, Char>>;
  1469. constexpr bool formattable =
  1470. std::is_constructible<formatter<mapped_type, Char>>::value;
  1471. if (!formattable) return ctx.begin(); // Error is reported in the value ctor.
  1472. using formatted_type = conditional_t<formattable, mapped_type, int>;
  1473. return formatter<formatted_type, Char>().parse(ctx);
  1474. }
  1475. template <typename... T> struct arg_pack {};
  1476. template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
  1477. class format_string_checker {
  1478. private:
  1479. type types_[max_of(1, NUM_ARGS)];
  1480. named_arg_info<Char> named_args_[max_of(1, NUM_NAMED_ARGS)];
  1481. compile_parse_context<Char> context_;
  1482. using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
  1483. parse_func parse_funcs_[max_of(1, NUM_ARGS)];
  1484. public:
  1485. template <typename... T>
  1486. FMT_CONSTEXPR explicit format_string_checker(basic_string_view<Char> fmt,
  1487. arg_pack<T...>)
  1488. : types_{mapped_type_constant<T, Char>::value...},
  1489. named_args_{},
  1490. context_(fmt, NUM_ARGS, types_),
  1491. parse_funcs_{&invoke_parse<T, Char>...} {
  1492. int arg_index = 0, named_arg_index = 0;
  1493. FMT_APPLY_VARIADIC(
  1494. init_static_named_arg<T>(named_args_, arg_index, named_arg_index));
  1495. ignore_unused(arg_index, named_arg_index);
  1496. }
  1497. FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
  1498. FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); }
  1499. FMT_CONSTEXPR auto on_arg_id(int id) -> int {
  1500. context_.check_arg_id(id);
  1501. return id;
  1502. }
  1503. FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
  1504. for (int i = 0; i < NUM_NAMED_ARGS; ++i) {
  1505. if (named_args_[i].name == id) return named_args_[i].id;
  1506. }
  1507. if (!DYNAMIC_NAMES) on_error("argument not found");
  1508. return -1;
  1509. }
  1510. FMT_CONSTEXPR void on_replacement_field(int id, const Char* begin) {
  1511. on_format_specs(id, begin, begin); // Call parse() on empty specs.
  1512. }
  1513. FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char* end)
  1514. -> const Char* {
  1515. context_.advance_to(begin);
  1516. if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
  1517. // If id is out of range, it means we do not know the type and cannot parse
  1518. // the format at compile time. Instead, skip over content until we finish
  1519. // the format spec, accounting for any nested replacements.
  1520. for (int bracket_count = 0;
  1521. begin != end && (bracket_count > 0 || *begin != '}'); ++begin) {
  1522. if (*begin == '{')
  1523. ++bracket_count;
  1524. else if (*begin == '}')
  1525. --bracket_count;
  1526. }
  1527. return begin;
  1528. }
  1529. FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) {
  1530. report_error(message);
  1531. }
  1532. };
  1533. /// A contiguous memory buffer with an optional growing ability. It is an
  1534. /// internal class and shouldn't be used directly, only via `memory_buffer`.
  1535. template <typename T> class buffer {
  1536. private:
  1537. T* ptr_;
  1538. size_t size_;
  1539. size_t capacity_;
  1540. using grow_fun = void (*)(buffer& buf, size_t capacity);
  1541. grow_fun grow_;
  1542. protected:
  1543. // Don't initialize ptr_ since it is not accessed to save a few cycles.
  1544. FMT_MSC_WARNING(suppress : 26495)
  1545. FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept
  1546. : size_(sz), capacity_(sz), grow_(grow) {}
  1547. constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,
  1548. size_t cap = 0) noexcept
  1549. : ptr_(p), size_(sz), capacity_(cap), grow_(grow) {}
  1550. FMT_CONSTEXPR20 ~buffer() = default;
  1551. buffer(buffer&&) = default;
  1552. /// Sets the buffer data and capacity.
  1553. FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept {
  1554. ptr_ = buf_data;
  1555. capacity_ = buf_capacity;
  1556. }
  1557. public:
  1558. using value_type = T;
  1559. using const_reference = const T&;
  1560. buffer(const buffer&) = delete;
  1561. void operator=(const buffer&) = delete;
  1562. auto begin() noexcept -> T* { return ptr_; }
  1563. auto end() noexcept -> T* { return ptr_ + size_; }
  1564. auto begin() const noexcept -> const T* { return ptr_; }
  1565. auto end() const noexcept -> const T* { return ptr_ + size_; }
  1566. /// Returns the size of this buffer.
  1567. constexpr auto size() const noexcept -> size_t { return size_; }
  1568. /// Returns the capacity of this buffer.
  1569. constexpr auto capacity() const noexcept -> size_t { return capacity_; }
  1570. /// Returns a pointer to the buffer data (not null-terminated).
  1571. FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; }
  1572. FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; }
  1573. /// Clears this buffer.
  1574. FMT_CONSTEXPR void clear() { size_ = 0; }
  1575. // Tries resizing the buffer to contain `count` elements. If T is a POD type
  1576. // the new elements may not be initialized.
  1577. FMT_CONSTEXPR void try_resize(size_t count) {
  1578. try_reserve(count);
  1579. size_ = min_of(count, capacity_);
  1580. }
  1581. // Tries increasing the buffer capacity to `new_capacity`. It can increase the
  1582. // capacity by a smaller amount than requested but guarantees there is space
  1583. // for at least one additional element either by increasing the capacity or by
  1584. // flushing the buffer if it is full.
  1585. FMT_CONSTEXPR void try_reserve(size_t new_capacity) {
  1586. if (new_capacity > capacity_) grow_(*this, new_capacity);
  1587. }
  1588. FMT_CONSTEXPR void push_back(const T& value) {
  1589. try_reserve(size_ + 1);
  1590. ptr_[size_++] = value;
  1591. }
  1592. /// Appends data to the end of the buffer.
  1593. template <typename U>
  1594. // Workaround for MSVC2019 to fix error C2893: Failed to specialize function
  1595. // template 'void fmt::v11::detail::buffer<T>::append(const U *,const U *)'.
  1596. #if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1940
  1597. FMT_CONSTEXPR20
  1598. #endif
  1599. void
  1600. append(const U* begin, const U* end) {
  1601. while (begin != end) {
  1602. auto count = to_unsigned(end - begin);
  1603. try_reserve(size_ + count);
  1604. auto free_cap = capacity_ - size_;
  1605. if (free_cap < count) count = free_cap;
  1606. // A loop is faster than memcpy on small sizes.
  1607. T* out = ptr_ + size_;
  1608. for (size_t i = 0; i < count; ++i) out[i] = begin[i];
  1609. size_ += count;
  1610. begin += count;
  1611. }
  1612. }
  1613. template <typename Idx> FMT_CONSTEXPR auto operator[](Idx index) -> T& {
  1614. return ptr_[index];
  1615. }
  1616. template <typename Idx>
  1617. FMT_CONSTEXPR auto operator[](Idx index) const -> const T& {
  1618. return ptr_[index];
  1619. }
  1620. };
  1621. struct buffer_traits {
  1622. constexpr explicit buffer_traits(size_t) {}
  1623. constexpr auto count() const -> size_t { return 0; }
  1624. constexpr auto limit(size_t size) const -> size_t { return size; }
  1625. };
  1626. class fixed_buffer_traits {
  1627. private:
  1628. size_t count_ = 0;
  1629. size_t limit_;
  1630. public:
  1631. constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
  1632. constexpr auto count() const -> size_t { return count_; }
  1633. FMT_CONSTEXPR auto limit(size_t size) -> size_t {
  1634. size_t n = limit_ > count_ ? limit_ - count_ : 0;
  1635. count_ += size;
  1636. return min_of(size, n);
  1637. }
  1638. };
  1639. // A buffer that writes to an output iterator when flushed.
  1640. template <typename OutputIt, typename T, typename Traits = buffer_traits>
  1641. class iterator_buffer : public Traits, public buffer<T> {
  1642. private:
  1643. OutputIt out_;
  1644. enum { buffer_size = 256 };
  1645. T data_[buffer_size];
  1646. static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
  1647. if (buf.size() == buffer_size) static_cast<iterator_buffer&>(buf).flush();
  1648. }
  1649. void flush() {
  1650. auto size = this->size();
  1651. this->clear();
  1652. const T* begin = data_;
  1653. const T* end = begin + this->limit(size);
  1654. while (begin != end) *out_++ = *begin++;
  1655. }
  1656. public:
  1657. explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
  1658. : Traits(n), buffer<T>(grow, data_, 0, buffer_size), out_(out) {}
  1659. iterator_buffer(iterator_buffer&& other) noexcept
  1660. : Traits(other),
  1661. buffer<T>(grow, data_, 0, buffer_size),
  1662. out_(other.out_) {}
  1663. ~iterator_buffer() {
  1664. // Don't crash if flush fails during unwinding.
  1665. FMT_TRY { flush(); }
  1666. FMT_CATCH(...) {}
  1667. }
  1668. auto out() -> OutputIt {
  1669. flush();
  1670. return out_;
  1671. }
  1672. auto count() const -> size_t { return Traits::count() + this->size(); }
  1673. };
  1674. template <typename T>
  1675. class iterator_buffer<T*, T, fixed_buffer_traits> : public fixed_buffer_traits,
  1676. public buffer<T> {
  1677. private:
  1678. T* out_;
  1679. enum { buffer_size = 256 };
  1680. T data_[buffer_size];
  1681. static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
  1682. if (buf.size() == buf.capacity())
  1683. static_cast<iterator_buffer&>(buf).flush();
  1684. }
  1685. void flush() {
  1686. size_t n = this->limit(this->size());
  1687. if (this->data() == out_) {
  1688. out_ += n;
  1689. this->set(data_, buffer_size);
  1690. }
  1691. this->clear();
  1692. }
  1693. public:
  1694. explicit iterator_buffer(T* out, size_t n = buffer_size)
  1695. : fixed_buffer_traits(n), buffer<T>(grow, out, 0, n), out_(out) {}
  1696. iterator_buffer(iterator_buffer&& other) noexcept
  1697. : fixed_buffer_traits(other),
  1698. buffer<T>(static_cast<iterator_buffer&&>(other)),
  1699. out_(other.out_) {
  1700. if (this->data() != out_) {
  1701. this->set(data_, buffer_size);
  1702. this->clear();
  1703. }
  1704. }
  1705. ~iterator_buffer() { flush(); }
  1706. auto out() -> T* {
  1707. flush();
  1708. return out_;
  1709. }
  1710. auto count() const -> size_t {
  1711. return fixed_buffer_traits::count() + this->size();
  1712. }
  1713. };
  1714. template <typename T> class iterator_buffer<T*, T> : public buffer<T> {
  1715. public:
  1716. explicit iterator_buffer(T* out, size_t = 0)
  1717. : buffer<T>([](buffer<T>&, size_t) {}, out, 0, ~size_t()) {}
  1718. auto out() -> T* { return &*this->end(); }
  1719. };
  1720. template <typename Container>
  1721. class container_buffer : public buffer<typename Container::value_type> {
  1722. private:
  1723. using value_type = typename Container::value_type;
  1724. static FMT_CONSTEXPR void grow(buffer<value_type>& buf, size_t capacity) {
  1725. auto& self = static_cast<container_buffer&>(buf);
  1726. self.container.resize(capacity);
  1727. self.set(&self.container[0], capacity);
  1728. }
  1729. public:
  1730. Container& container;
  1731. explicit container_buffer(Container& c)
  1732. : buffer<value_type>(grow, c.size()), container(c) {}
  1733. };
  1734. // A buffer that writes to a container with the contiguous storage.
  1735. template <typename OutputIt>
  1736. class iterator_buffer<
  1737. OutputIt,
  1738. enable_if_t<is_back_insert_iterator<OutputIt>::value &&
  1739. is_contiguous<typename OutputIt::container_type>::value,
  1740. typename OutputIt::container_type::value_type>>
  1741. : public container_buffer<typename OutputIt::container_type> {
  1742. private:
  1743. using base = container_buffer<typename OutputIt::container_type>;
  1744. public:
  1745. explicit iterator_buffer(typename OutputIt::container_type& c) : base(c) {}
  1746. explicit iterator_buffer(OutputIt out, size_t = 0)
  1747. : base(get_container(out)) {}
  1748. auto out() -> OutputIt { return OutputIt(this->container); }
  1749. };
  1750. // A buffer that counts the number of code units written discarding the output.
  1751. template <typename T = char> class counting_buffer : public buffer<T> {
  1752. private:
  1753. enum { buffer_size = 256 };
  1754. T data_[buffer_size];
  1755. size_t count_ = 0;
  1756. static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
  1757. if (buf.size() != buffer_size) return;
  1758. static_cast<counting_buffer&>(buf).count_ += buf.size();
  1759. buf.clear();
  1760. }
  1761. public:
  1762. FMT_CONSTEXPR counting_buffer() : buffer<T>(grow, data_, 0, buffer_size) {}
  1763. constexpr auto count() const noexcept -> size_t {
  1764. return count_ + this->size();
  1765. }
  1766. };
  1767. template <typename T>
  1768. struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
  1769. template <typename OutputIt, typename InputIt, typename = void>
  1770. struct has_back_insert_iterator_container_append : std::false_type {};
  1771. template <typename OutputIt, typename InputIt>
  1772. struct has_back_insert_iterator_container_append<
  1773. OutputIt, InputIt,
  1774. void_t<decltype(get_container(std::declval<OutputIt>())
  1775. .append(std::declval<InputIt>(),
  1776. std::declval<InputIt>()))>> : std::true_type {};
  1777. // An optimized version of std::copy with the output value type (T).
  1778. template <typename T, typename InputIt, typename OutputIt,
  1779. FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
  1780. has_back_insert_iterator_container_append<
  1781. OutputIt, InputIt>::value)>
  1782. FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
  1783. -> OutputIt {
  1784. get_container(out).append(begin, end);
  1785. return out;
  1786. }
  1787. template <typename T, typename InputIt, typename OutputIt,
  1788. FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
  1789. !has_back_insert_iterator_container_append<
  1790. OutputIt, InputIt>::value)>
  1791. FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
  1792. -> OutputIt {
  1793. auto& c = get_container(out);
  1794. c.insert(c.end(), begin, end);
  1795. return out;
  1796. }
  1797. template <typename T, typename InputIt, typename OutputIt,
  1798. FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
  1799. FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
  1800. while (begin != end) *out++ = static_cast<T>(*begin++);
  1801. return out;
  1802. }
  1803. template <typename T, typename V, typename OutputIt>
  1804. FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
  1805. return copy<T>(s.begin(), s.end(), out);
  1806. }
  1807. template <typename It, typename Enable = std::true_type>
  1808. struct is_buffer_appender : std::false_type {};
  1809. template <typename It>
  1810. struct is_buffer_appender<
  1811. It, bool_constant<
  1812. is_back_insert_iterator<It>::value &&
  1813. std::is_base_of<buffer<typename It::container_type::value_type>,
  1814. typename It::container_type>::value>>
  1815. : std::true_type {};
  1816. // Maps an output iterator to a buffer.
  1817. template <typename T, typename OutputIt,
  1818. FMT_ENABLE_IF(!is_buffer_appender<OutputIt>::value)>
  1819. auto get_buffer(OutputIt out) -> iterator_buffer<OutputIt, T> {
  1820. return iterator_buffer<OutputIt, T>(out);
  1821. }
  1822. template <typename T, typename OutputIt,
  1823. FMT_ENABLE_IF(is_buffer_appender<OutputIt>::value)>
  1824. auto get_buffer(OutputIt out) -> buffer<T>& {
  1825. return get_container(out);
  1826. }
  1827. template <typename Buf, typename OutputIt>
  1828. auto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) {
  1829. return buf.out();
  1830. }
  1831. template <typename T, typename OutputIt>
  1832. auto get_iterator(buffer<T>&, OutputIt out) -> OutputIt {
  1833. return out;
  1834. }
  1835. // This type is intentionally undefined, only used for errors.
  1836. template <typename T, typename Char> struct type_is_unformattable_for;
  1837. template <typename Char> struct string_value {
  1838. const Char* data;
  1839. size_t size;
  1840. auto str() const -> basic_string_view<Char> { return {data, size}; }
  1841. };
  1842. template <typename Context> struct custom_value {
  1843. using char_type = typename Context::char_type;
  1844. void* value;
  1845. void (*format)(void* arg, parse_context<char_type>& parse_ctx, Context& ctx);
  1846. };
  1847. template <typename Char> struct named_arg_value {
  1848. const named_arg_info<Char>* data;
  1849. size_t size;
  1850. };
  1851. struct custom_tag {};
  1852. #if !FMT_BUILTIN_TYPES
  1853. # define FMT_BUILTIN , monostate
  1854. #else
  1855. # define FMT_BUILTIN
  1856. #endif
  1857. // A formatting argument value.
  1858. template <typename Context> class value {
  1859. public:
  1860. using char_type = typename Context::char_type;
  1861. union {
  1862. monostate no_value;
  1863. int int_value;
  1864. unsigned uint_value;
  1865. long long long_long_value;
  1866. unsigned long long ulong_long_value;
  1867. int128_opt int128_value;
  1868. uint128_opt uint128_value;
  1869. bool bool_value;
  1870. char_type char_value;
  1871. float float_value;
  1872. double double_value;
  1873. long double long_double_value;
  1874. const void* pointer;
  1875. string_value<char_type> string;
  1876. custom_value<Context> custom;
  1877. named_arg_value<char_type> named_args;
  1878. };
  1879. constexpr FMT_INLINE value() : no_value() {}
  1880. constexpr FMT_INLINE value(signed char x) : int_value(x) {}
  1881. constexpr FMT_INLINE value(unsigned char x FMT_BUILTIN) : uint_value(x) {}
  1882. constexpr FMT_INLINE value(signed short x) : int_value(x) {}
  1883. constexpr FMT_INLINE value(unsigned short x FMT_BUILTIN) : uint_value(x) {}
  1884. constexpr FMT_INLINE value(int x) : int_value(x) {}
  1885. constexpr FMT_INLINE value(unsigned x FMT_BUILTIN) : uint_value(x) {}
  1886. FMT_CONSTEXPR FMT_INLINE value(long x FMT_BUILTIN) : value(long_type(x)) {}
  1887. FMT_CONSTEXPR FMT_INLINE value(unsigned long x FMT_BUILTIN)
  1888. : value(ulong_type(x)) {}
  1889. constexpr FMT_INLINE value(long long x FMT_BUILTIN) : long_long_value(x) {}
  1890. constexpr FMT_INLINE value(unsigned long long x FMT_BUILTIN)
  1891. : ulong_long_value(x) {}
  1892. FMT_INLINE value(int128_opt x FMT_BUILTIN) : int128_value(x) {}
  1893. FMT_INLINE value(uint128_opt x FMT_BUILTIN) : uint128_value(x) {}
  1894. constexpr FMT_INLINE value(bool x FMT_BUILTIN) : bool_value(x) {}
  1895. template <int N>
  1896. constexpr FMT_INLINE value(bitint<N> x FMT_BUILTIN) : long_long_value(x) {
  1897. static_assert(N <= 64, "unsupported _BitInt");
  1898. }
  1899. template <int N>
  1900. constexpr FMT_INLINE value(ubitint<N> x FMT_BUILTIN) : ulong_long_value(x) {
  1901. static_assert(N <= 64, "unsupported _BitInt");
  1902. }
  1903. template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
  1904. constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) {
  1905. static_assert(
  1906. std::is_same<T, char>::value || std::is_same<T, char_type>::value,
  1907. "mixing character types is disallowed");
  1908. }
  1909. constexpr FMT_INLINE value(float x FMT_BUILTIN) : float_value(x) {}
  1910. constexpr FMT_INLINE value(double x FMT_BUILTIN) : double_value(x) {}
  1911. FMT_INLINE value(long double x FMT_BUILTIN) : long_double_value(x) {}
  1912. FMT_CONSTEXPR FMT_INLINE value(char_type* x FMT_BUILTIN) {
  1913. string.data = x;
  1914. if (is_constant_evaluated()) string.size = 0;
  1915. }
  1916. FMT_CONSTEXPR FMT_INLINE value(const char_type* x FMT_BUILTIN) {
  1917. string.data = x;
  1918. if (is_constant_evaluated()) string.size = 0;
  1919. }
  1920. template <typename T, typename C = char_t<T>,
  1921. FMT_ENABLE_IF(!std::is_pointer<T>::value)>
  1922. FMT_CONSTEXPR value(const T& x FMT_BUILTIN) {
  1923. static_assert(std::is_same<C, char_type>::value,
  1924. "mixing character types is disallowed");
  1925. auto sv = to_string_view(x);
  1926. string.data = sv.data();
  1927. string.size = sv.size();
  1928. }
  1929. FMT_INLINE value(void* x FMT_BUILTIN) : pointer(x) {}
  1930. FMT_INLINE value(const void* x FMT_BUILTIN) : pointer(x) {}
  1931. FMT_INLINE value(volatile void* x FMT_BUILTIN)
  1932. : pointer(const_cast<const void*>(x)) {}
  1933. FMT_INLINE value(const volatile void* x FMT_BUILTIN)
  1934. : pointer(const_cast<const void*>(x)) {}
  1935. FMT_INLINE value(nullptr_t) : pointer(nullptr) {}
  1936. template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
  1937. std::is_member_pointer<T>::value)>
  1938. value(const T&) {
  1939. // Formatting of arbitrary pointers is disallowed. If you want to format a
  1940. // pointer cast it to `void*` or `const void*`. In particular, this forbids
  1941. // formatting of `[const] volatile char*` printed as bool by iostreams.
  1942. static_assert(sizeof(T) == 0,
  1943. "formatting of non-void pointers is disallowed");
  1944. }
  1945. template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
  1946. value(const T& x) : value(format_as(x)) {}
  1947. template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>
  1948. value(const T& x) : value(formatter<T>::format_as(x)) {}
  1949. template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
  1950. value(const T& named_arg) : value(named_arg.value) {}
  1951. template <typename T,
  1952. FMT_ENABLE_IF(use_formatter<T>::value || !FMT_BUILTIN_TYPES)>
  1953. FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
  1954. FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)
  1955. : named_args{args, size} {}
  1956. private:
  1957. template <typename T, FMT_ENABLE_IF(has_formatter<T, char_type>())>
  1958. FMT_CONSTEXPR value(T& x, custom_tag) {
  1959. using value_type = remove_const_t<T>;
  1960. // T may overload operator& e.g. std::vector<bool>::reference in libc++.
  1961. if (!is_constant_evaluated()) {
  1962. custom.value =
  1963. const_cast<char*>(&reinterpret_cast<const volatile char&>(x));
  1964. } else {
  1965. custom.value = nullptr;
  1966. #if defined(__cpp_if_constexpr)
  1967. if constexpr (std::is_same<decltype(&x), remove_reference_t<T>*>::value)
  1968. custom.value = const_cast<value_type*>(&x);
  1969. #endif
  1970. }
  1971. custom.format = format_custom<value_type, formatter<value_type, char_type>>;
  1972. }
  1973. template <typename T, FMT_ENABLE_IF(!has_formatter<T, char_type>())>
  1974. FMT_CONSTEXPR value(const T&, custom_tag) {
  1975. // Cannot format an argument; to make type T formattable provide a
  1976. // formatter<T> specialization: https://fmt.dev/latest/api.html#udt.
  1977. type_is_unformattable_for<T, char_type> _;
  1978. }
  1979. // Formats an argument of a custom type, such as a user-defined class.
  1980. template <typename T, typename Formatter>
  1981. static void format_custom(void* arg, parse_context<char_type>& parse_ctx,
  1982. Context& ctx) {
  1983. auto f = Formatter();
  1984. parse_ctx.advance_to(f.parse(parse_ctx));
  1985. using qualified_type =
  1986. conditional_t<has_formatter<const T, char_type>(), const T, T>;
  1987. // format must be const for compatibility with std::format and compilation.
  1988. const auto& cf = f;
  1989. ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));
  1990. }
  1991. };
  1992. enum { packed_arg_bits = 4 };
  1993. // Maximum number of arguments with packed types.
  1994. enum { max_packed_args = 62 / packed_arg_bits };
  1995. enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
  1996. enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
  1997. template <typename It, typename T, typename Enable = void>
  1998. struct is_output_iterator : std::false_type {};
  1999. template <> struct is_output_iterator<appender, char> : std::true_type {};
  2000. template <typename It, typename T>
  2001. struct is_output_iterator<
  2002. It, T,
  2003. enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),
  2004. T>::value>> : std::true_type {};
  2005. #ifndef FMT_USE_LOCALE
  2006. # define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
  2007. #endif
  2008. // A type-erased reference to an std::locale to avoid a heavy <locale> include.
  2009. class locale_ref {
  2010. #if FMT_USE_LOCALE
  2011. private:
  2012. const void* locale_; // A type-erased pointer to std::locale.
  2013. public:
  2014. constexpr locale_ref() : locale_(nullptr) {}
  2015. template <typename Locale> locale_ref(const Locale& loc);
  2016. inline explicit operator bool() const noexcept { return locale_ != nullptr; }
  2017. #endif // FMT_USE_LOCALE
  2018. public:
  2019. template <typename Locale> auto get() const -> Locale;
  2020. };
  2021. template <typename> constexpr auto encode_types() -> unsigned long long {
  2022. return 0;
  2023. }
  2024. template <typename Context, typename Arg, typename... Args>
  2025. constexpr auto encode_types() -> unsigned long long {
  2026. return static_cast<unsigned>(stored_type_constant<Arg, Context>::value) |
  2027. (encode_types<Context, Args...>() << packed_arg_bits);
  2028. }
  2029. template <typename Context, typename... T, size_t NUM_ARGS = sizeof...(T)>
  2030. constexpr auto make_descriptor() -> unsigned long long {
  2031. return NUM_ARGS <= max_packed_args ? encode_types<Context, T...>()
  2032. : is_unpacked_bit | NUM_ARGS;
  2033. }
  2034. template <typename Context, int NUM_ARGS>
  2035. using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
  2036. basic_format_arg<Context>>;
  2037. template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
  2038. unsigned long long DESC>
  2039. struct named_arg_store {
  2040. // args_[0].named_args points to named_args to avoid bloating format_args.
  2041. arg_t<Context, NUM_ARGS> args[1 + NUM_ARGS];
  2042. named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];
  2043. template <typename... T>
  2044. FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values)
  2045. : args{{named_args, NUM_NAMED_ARGS}, values...} {
  2046. int arg_index = 0, named_arg_index = 0;
  2047. FMT_APPLY_VARIADIC(
  2048. init_named_arg(named_args, arg_index, named_arg_index, values));
  2049. }
  2050. named_arg_store(named_arg_store&& rhs) {
  2051. args[0] = {named_args, NUM_NAMED_ARGS};
  2052. for (size_t i = 1; i < sizeof(args) / sizeof(*args); ++i)
  2053. args[i] = rhs.args[i];
  2054. for (size_t i = 0; i < NUM_NAMED_ARGS; ++i)
  2055. named_args[i] = rhs.named_args[i];
  2056. }
  2057. named_arg_store(const named_arg_store& rhs) = delete;
  2058. named_arg_store& operator=(const named_arg_store& rhs) = delete;
  2059. named_arg_store& operator=(named_arg_store&& rhs) = delete;
  2060. operator const arg_t<Context, NUM_ARGS>*() const { return args + 1; }
  2061. };
  2062. // An array of references to arguments. It can be implicitly converted to
  2063. // `basic_format_args` for passing into type-erased formatting functions
  2064. // such as `vformat`. It is a plain struct to reduce binary size in debug mode.
  2065. template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
  2066. unsigned long long DESC>
  2067. struct format_arg_store {
  2068. // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
  2069. using type =
  2070. conditional_t<NUM_NAMED_ARGS == 0,
  2071. arg_t<Context, NUM_ARGS>[max_of(1, NUM_ARGS)],
  2072. named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
  2073. type args;
  2074. };
  2075. // TYPE can be different from type_constant<T>, e.g. for __float128.
  2076. template <typename T, typename Char, type TYPE> struct native_formatter {
  2077. private:
  2078. dynamic_format_specs<Char> specs_;
  2079. public:
  2080. using nonlocking = void;
  2081. FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
  2082. if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
  2083. auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE);
  2084. if (const_check(TYPE == type::char_type)) check_char_specs(specs_);
  2085. return end;
  2086. }
  2087. template <type U = TYPE,
  2088. FMT_ENABLE_IF(U == type::string_type || U == type::cstring_type ||
  2089. U == type::char_type)>
  2090. FMT_CONSTEXPR void set_debug_format(bool set = true) {
  2091. specs_.set_type(set ? presentation_type::debug : presentation_type::none);
  2092. }
  2093. FMT_PRAGMA_CLANG(diagnostic ignored "-Wundefined-inline")
  2094. template <typename FormatContext>
  2095. FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
  2096. -> decltype(ctx.out());
  2097. };
  2098. template <typename T, typename Enable = void>
  2099. struct locking
  2100. : bool_constant<mapped_type_constant<T>::value == type::custom_type> {};
  2101. template <typename T>
  2102. struct locking<T, void_t<typename formatter<remove_cvref_t<T>>::nonlocking>>
  2103. : std::false_type {};
  2104. template <typename T = int> FMT_CONSTEXPR inline auto is_locking() -> bool {
  2105. return locking<T>::value;
  2106. }
  2107. template <typename T1, typename T2, typename... Tail>
  2108. FMT_CONSTEXPR inline auto is_locking() -> bool {
  2109. return locking<T1>::value || is_locking<T2, Tail...>();
  2110. }
  2111. FMT_API void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
  2112. locale_ref loc = {});
  2113. #if FMT_WIN32
  2114. FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool);
  2115. #else // format_args is passed by reference since it is defined later.
  2116. inline void vprint_mojibake(FILE*, string_view, const format_args&, bool) {}
  2117. #endif
  2118. } // namespace detail
  2119. // The main public API.
  2120. template <typename Char>
  2121. FMT_CONSTEXPR void parse_context<Char>::do_check_arg_id(int arg_id) {
  2122. // Argument id is only checked at compile time during parsing because
  2123. // formatting has its own validation.
  2124. if (detail::is_constant_evaluated() && use_constexpr_cast) {
  2125. auto ctx = static_cast<detail::compile_parse_context<Char>*>(this);
  2126. if (arg_id >= ctx->num_args()) report_error("argument not found");
  2127. }
  2128. }
  2129. template <typename Char>
  2130. FMT_CONSTEXPR void parse_context<Char>::check_dynamic_spec(int arg_id) {
  2131. using detail::compile_parse_context;
  2132. if (detail::is_constant_evaluated() && use_constexpr_cast)
  2133. static_cast<compile_parse_context<Char>*>(this)->check_dynamic_spec(arg_id);
  2134. }
  2135. FMT_BEGIN_EXPORT
  2136. // An output iterator that appends to a buffer. It is used instead of
  2137. // back_insert_iterator to reduce symbol sizes and avoid <iterator> dependency.
  2138. template <typename T> class basic_appender {
  2139. protected:
  2140. detail::buffer<T>* container;
  2141. public:
  2142. using container_type = detail::buffer<T>;
  2143. FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : container(&buf) {}
  2144. FMT_CONSTEXPR20 auto operator=(T c) -> basic_appender& {
  2145. container->push_back(c);
  2146. return *this;
  2147. }
  2148. FMT_CONSTEXPR20 auto operator*() -> basic_appender& { return *this; }
  2149. FMT_CONSTEXPR20 auto operator++() -> basic_appender& { return *this; }
  2150. FMT_CONSTEXPR20 auto operator++(int) -> basic_appender { return *this; }
  2151. };
  2152. // A formatting argument. Context is a template parameter for the compiled API
  2153. // where output can be unbuffered.
  2154. template <typename Context> class basic_format_arg {
  2155. private:
  2156. detail::value<Context> value_;
  2157. detail::type type_;
  2158. friend class basic_format_args<Context>;
  2159. using char_type = typename Context::char_type;
  2160. public:
  2161. class handle {
  2162. private:
  2163. detail::custom_value<Context> custom_;
  2164. public:
  2165. explicit handle(detail::custom_value<Context> custom) : custom_(custom) {}
  2166. void format(parse_context<char_type>& parse_ctx, Context& ctx) const {
  2167. custom_.format(custom_.value, parse_ctx, ctx);
  2168. }
  2169. };
  2170. constexpr basic_format_arg() : type_(detail::type::none_type) {}
  2171. basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
  2172. : value_(args, size) {}
  2173. template <typename T>
  2174. basic_format_arg(T&& val)
  2175. : value_(val), type_(detail::stored_type_constant<T, Context>::value) {}
  2176. constexpr explicit operator bool() const noexcept {
  2177. return type_ != detail::type::none_type;
  2178. }
  2179. auto type() const -> detail::type { return type_; }
  2180. /**
  2181. * Visits an argument dispatching to the appropriate visit method based on
  2182. * the argument type. For example, if the argument type is `double` then
  2183. * `vis(value)` will be called with the value of type `double`.
  2184. */
  2185. template <typename Visitor>
  2186. FMT_CONSTEXPR FMT_INLINE auto visit(Visitor&& vis) const -> decltype(vis(0)) {
  2187. using detail::map;
  2188. switch (type_) {
  2189. case detail::type::none_type: break;
  2190. case detail::type::int_type: return vis(value_.int_value);
  2191. case detail::type::uint_type: return vis(value_.uint_value);
  2192. case detail::type::long_long_type: return vis(value_.long_long_value);
  2193. case detail::type::ulong_long_type: return vis(value_.ulong_long_value);
  2194. case detail::type::int128_type: return vis(map(value_.int128_value));
  2195. case detail::type::uint128_type: return vis(map(value_.uint128_value));
  2196. case detail::type::bool_type: return vis(value_.bool_value);
  2197. case detail::type::char_type: return vis(value_.char_value);
  2198. case detail::type::float_type: return vis(value_.float_value);
  2199. case detail::type::double_type: return vis(value_.double_value);
  2200. case detail::type::long_double_type: return vis(value_.long_double_value);
  2201. case detail::type::cstring_type: return vis(value_.string.data);
  2202. case detail::type::string_type: return vis(value_.string.str());
  2203. case detail::type::pointer_type: return vis(value_.pointer);
  2204. case detail::type::custom_type: return vis(handle(value_.custom));
  2205. }
  2206. return vis(monostate());
  2207. }
  2208. auto format_custom(const char_type* parse_begin,
  2209. parse_context<char_type>& parse_ctx, Context& ctx)
  2210. -> bool {
  2211. if (type_ != detail::type::custom_type) return false;
  2212. parse_ctx.advance_to(parse_begin);
  2213. value_.custom.format(value_.custom.value, parse_ctx, ctx);
  2214. return true;
  2215. }
  2216. };
  2217. /**
  2218. * A view of a collection of formatting arguments. To avoid lifetime issues it
  2219. * should only be used as a parameter type in type-erased functions such as
  2220. * `vformat`:
  2221. *
  2222. * void vlog(fmt::string_view fmt, fmt::format_args args); // OK
  2223. * fmt::format_args args = fmt::make_format_args(); // Dangling reference
  2224. */
  2225. template <typename Context> class basic_format_args {
  2226. private:
  2227. // A descriptor that contains information about formatting arguments.
  2228. // If the number of arguments is less or equal to max_packed_args then
  2229. // argument types are passed in the descriptor. This reduces binary code size
  2230. // per formatting function call.
  2231. unsigned long long desc_;
  2232. union {
  2233. // If is_packed() returns true then argument values are stored in values_;
  2234. // otherwise they are stored in args_. This is done to improve cache
  2235. // locality and reduce compiled code size since storing larger objects
  2236. // may require more code (at least on x86-64) even if the same amount of
  2237. // data is actually copied to stack. It saves ~10% on the bloat test.
  2238. const detail::value<Context>* values_;
  2239. const basic_format_arg<Context>* args_;
  2240. };
  2241. constexpr auto is_packed() const -> bool {
  2242. return (desc_ & detail::is_unpacked_bit) == 0;
  2243. }
  2244. constexpr auto has_named_args() const -> bool {
  2245. return (desc_ & detail::has_named_args_bit) != 0;
  2246. }
  2247. FMT_CONSTEXPR auto type(int index) const -> detail::type {
  2248. int shift = index * detail::packed_arg_bits;
  2249. unsigned mask = (1 << detail::packed_arg_bits) - 1;
  2250. return static_cast<detail::type>((desc_ >> shift) & mask);
  2251. }
  2252. template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC>
  2253. using store =
  2254. detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>;
  2255. public:
  2256. using format_arg = basic_format_arg<Context>;
  2257. constexpr basic_format_args() : desc_(0), args_(nullptr) {}
  2258. /// Constructs a `basic_format_args` object from `format_arg_store`.
  2259. template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,
  2260. FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args)>
  2261. constexpr FMT_ALWAYS_INLINE basic_format_args(
  2262. const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
  2263. : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
  2264. values_(s.args) {}
  2265. template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,
  2266. FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>
  2267. constexpr basic_format_args(const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
  2268. : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
  2269. args_(s.args) {}
  2270. /// Constructs a `basic_format_args` object from a dynamic list of arguments.
  2271. constexpr basic_format_args(const format_arg* args, int count,
  2272. bool has_named = false)
  2273. : desc_(detail::is_unpacked_bit | detail::to_unsigned(count) |
  2274. (has_named ? +detail::has_named_args_bit : 0)),
  2275. args_(args) {}
  2276. /// Returns the argument with the specified id.
  2277. FMT_CONSTEXPR auto get(int id) const -> format_arg {
  2278. auto arg = format_arg();
  2279. if (!is_packed()) {
  2280. if (id < max_size()) arg = args_[id];
  2281. return arg;
  2282. }
  2283. if (static_cast<unsigned>(id) >= detail::max_packed_args) return arg;
  2284. arg.type_ = type(id);
  2285. if (arg.type_ != detail::type::none_type) arg.value_ = values_[id];
  2286. return arg;
  2287. }
  2288. template <typename Char>
  2289. auto get(basic_string_view<Char> name) const -> format_arg {
  2290. int id = get_id(name);
  2291. return id >= 0 ? get(id) : format_arg();
  2292. }
  2293. template <typename Char>
  2294. FMT_CONSTEXPR auto get_id(basic_string_view<Char> name) const -> int {
  2295. if (!has_named_args()) return -1;
  2296. const auto& named_args =
  2297. (is_packed() ? values_[-1] : args_[-1].value_).named_args;
  2298. for (size_t i = 0; i < named_args.size; ++i) {
  2299. if (named_args.data[i].name == name) return named_args.data[i].id;
  2300. }
  2301. return -1;
  2302. }
  2303. auto max_size() const -> int {
  2304. unsigned long long max_packed = detail::max_packed_args;
  2305. return static_cast<int>(is_packed() ? max_packed
  2306. : desc_ & ~detail::is_unpacked_bit);
  2307. }
  2308. };
  2309. // A formatting context.
  2310. class context {
  2311. private:
  2312. appender out_;
  2313. format_args args_;
  2314. FMT_NO_UNIQUE_ADDRESS detail::locale_ref loc_;
  2315. public:
  2316. /// The character type for the output.
  2317. using char_type = char;
  2318. using iterator = appender;
  2319. using format_arg = basic_format_arg<context>;
  2320. using parse_context_type FMT_DEPRECATED = parse_context<>;
  2321. template <typename T> using formatter_type FMT_DEPRECATED = formatter<T>;
  2322. enum { builtin_types = FMT_BUILTIN_TYPES };
  2323. /// Constructs a `context` object. References to the arguments are stored
  2324. /// in the object so make sure they have appropriate lifetimes.
  2325. FMT_CONSTEXPR context(iterator out, format_args args,
  2326. detail::locale_ref loc = {})
  2327. : out_(out), args_(args), loc_(loc) {}
  2328. context(context&&) = default;
  2329. context(const context&) = delete;
  2330. void operator=(const context&) = delete;
  2331. FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }
  2332. inline auto arg(string_view name) const -> format_arg {
  2333. return args_.get(name);
  2334. }
  2335. FMT_CONSTEXPR auto arg_id(string_view name) const -> int {
  2336. return args_.get_id(name);
  2337. }
  2338. auto args() const -> const format_args& { return args_; }
  2339. // Returns an iterator to the beginning of the output range.
  2340. FMT_CONSTEXPR auto out() const -> iterator { return out_; }
  2341. // Advances the begin iterator to `it`.
  2342. FMT_CONSTEXPR void advance_to(iterator) {}
  2343. FMT_CONSTEXPR auto locale() const -> detail::locale_ref { return loc_; }
  2344. };
  2345. template <typename Char = char> struct runtime_format_string {
  2346. basic_string_view<Char> str;
  2347. };
  2348. /**
  2349. * Creates a runtime format string.
  2350. *
  2351. * **Example**:
  2352. *
  2353. * // Check format string at runtime instead of compile-time.
  2354. * fmt::print(fmt::runtime("{:d}"), "I am not a number");
  2355. */
  2356. inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
  2357. /// A compile-time format string. Use `format_string` in the public API to
  2358. /// prevent type deduction.
  2359. template <typename... T> struct fstring {
  2360. private:
  2361. static constexpr int num_static_named_args =
  2362. detail::count_static_named_args<T...>();
  2363. using checker = detail::format_string_checker<
  2364. char, static_cast<int>(sizeof...(T)), num_static_named_args,
  2365. num_static_named_args != detail::count_named_args<T...>()>;
  2366. using arg_pack = detail::arg_pack<T...>;
  2367. public:
  2368. string_view str;
  2369. using t = fstring;
  2370. // Reports a compile-time error if S is not a valid format string for T.
  2371. template <size_t N>
  2372. FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) {
  2373. using namespace detail;
  2374. static_assert(count<(std::is_base_of<view, remove_reference_t<T>>::value &&
  2375. std::is_reference<T>::value)...>() == 0,
  2376. "passing views as lvalues is disallowed");
  2377. if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));
  2378. #ifdef FMT_ENFORCE_COMPILE_STRING
  2379. static_assert(
  2380. FMT_USE_CONSTEVAL && sizeof(s) != 0,
  2381. "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING");
  2382. #endif
  2383. }
  2384. template <typename S,
  2385. FMT_ENABLE_IF(std::is_convertible<const S&, string_view>::value)>
  2386. FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) {
  2387. auto sv = string_view(str);
  2388. if (FMT_USE_CONSTEVAL)
  2389. detail::parse_format_string<char>(sv, checker(sv, arg_pack()));
  2390. #ifdef FMT_ENFORCE_COMPILE_STRING
  2391. static_assert(
  2392. FMT_USE_CONSTEVAL && sizeof(s) != 0,
  2393. "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING");
  2394. #endif
  2395. }
  2396. template <typename S,
  2397. FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
  2398. std::is_same<typename S::char_type, char>::value)>
  2399. FMT_ALWAYS_INLINE fstring(const S&) : str(S()) {
  2400. FMT_CONSTEXPR auto sv = string_view(S());
  2401. FMT_CONSTEXPR int unused =
  2402. (parse_format_string(sv, checker(sv, arg_pack())), 0);
  2403. detail::ignore_unused(unused);
  2404. }
  2405. fstring(runtime_format_string<> fmt) : str(fmt.str) {}
  2406. // Returning by reference generates better code in debug mode.
  2407. FMT_ALWAYS_INLINE operator const string_view&() const { return str; }
  2408. auto get() const -> string_view { return str; }
  2409. };
  2410. template <typename... T> using format_string = typename fstring<T...>::t;
  2411. template <typename T, typename Char = char>
  2412. using is_formattable = bool_constant<!std::is_same<
  2413. detail::mapped_t<conditional_t<std::is_void<T>::value, int*, T>, Char>,
  2414. void>::value>;
  2415. #ifdef __cpp_concepts
  2416. template <typename T, typename Char = char>
  2417. concept formattable = is_formattable<remove_reference_t<T>, Char>::value;
  2418. #endif
  2419. template <typename T, typename Char>
  2420. using has_formatter FMT_DEPRECATED = std::is_constructible<formatter<T, Char>>;
  2421. // A formatter specialization for natively supported types.
  2422. template <typename T, typename Char>
  2423. struct formatter<T, Char,
  2424. enable_if_t<detail::type_constant<T, Char>::value !=
  2425. detail::type::custom_type>>
  2426. : detail::native_formatter<T, Char, detail::type_constant<T, Char>::value> {
  2427. };
  2428. /**
  2429. * Constructs an object that stores references to arguments and can be
  2430. * implicitly converted to `format_args`. `Context` can be omitted in which case
  2431. * it defaults to `context`. See `arg` for lifetime considerations.
  2432. */
  2433. // Take arguments by lvalue references to avoid some lifetime issues, e.g.
  2434. // auto args = make_format_args(std::string());
  2435. template <typename Context = context, typename... T,
  2436. int NUM_ARGS = sizeof...(T),
  2437. int NUM_NAMED_ARGS = detail::count_named_args<T...>(),
  2438. unsigned long long DESC = detail::make_descriptor<Context, T...>()>
  2439. constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)
  2440. -> detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC> {
  2441. // Suppress warnings for pathological types convertible to detail::value.
  2442. FMT_PRAGMA_GCC(diagnostic ignored "-Wconversion")
  2443. return {{args...}};
  2444. }
  2445. template <typename... T>
  2446. using vargs =
  2447. detail::format_arg_store<context, sizeof...(T),
  2448. detail::count_named_args<T...>(),
  2449. detail::make_descriptor<context, T...>()>;
  2450. /**
  2451. * Returns a named argument to be used in a formatting function.
  2452. * It should only be used in a call to a formatting function.
  2453. *
  2454. * **Example**:
  2455. *
  2456. * fmt::print("The answer is {answer}.", fmt::arg("answer", 42));
  2457. */
  2458. template <typename Char, typename T>
  2459. inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
  2460. return {name, arg};
  2461. }
  2462. /// Formats a string and writes the output to `out`.
  2463. template <typename OutputIt,
  2464. FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
  2465. char>::value)>
  2466. auto vformat_to(OutputIt&& out, string_view fmt, format_args args)
  2467. -> remove_cvref_t<OutputIt> {
  2468. auto&& buf = detail::get_buffer<char>(out);
  2469. detail::vformat_to(buf, fmt, args, {});
  2470. return detail::get_iterator(buf, out);
  2471. }
  2472. /**
  2473. * Formats `args` according to specifications in `fmt`, writes the result to
  2474. * the output iterator `out` and returns the iterator past the end of the output
  2475. * range. `format_to` does not append a terminating null character.
  2476. *
  2477. * **Example**:
  2478. *
  2479. * auto out = std::vector<char>();
  2480. * fmt::format_to(std::back_inserter(out), "{}", 42);
  2481. */
  2482. template <typename OutputIt, typename... T,
  2483. FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
  2484. char>::value)>
  2485. FMT_INLINE auto format_to(OutputIt&& out, format_string<T...> fmt, T&&... args)
  2486. -> remove_cvref_t<OutputIt> {
  2487. return vformat_to(out, fmt.str, vargs<T...>{{args...}});
  2488. }
  2489. template <typename OutputIt> struct format_to_n_result {
  2490. /// Iterator past the end of the output range.
  2491. OutputIt out;
  2492. /// Total (not truncated) output size.
  2493. size_t size;
  2494. };
  2495. template <typename OutputIt, typename... T,
  2496. FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
  2497. auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)
  2498. -> format_to_n_result<OutputIt> {
  2499. using traits = detail::fixed_buffer_traits;
  2500. auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
  2501. detail::vformat_to(buf, fmt, args, {});
  2502. return {buf.out(), buf.count()};
  2503. }
  2504. /**
  2505. * Formats `args` according to specifications in `fmt`, writes up to `n`
  2506. * characters of the result to the output iterator `out` and returns the total
  2507. * (not truncated) output size and the iterator past the end of the output
  2508. * range. `format_to_n` does not append a terminating null character.
  2509. */
  2510. template <typename OutputIt, typename... T,
  2511. FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
  2512. FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,
  2513. T&&... args) -> format_to_n_result<OutputIt> {
  2514. return vformat_to_n(out, n, fmt.str, vargs<T...>{{args...}});
  2515. }
  2516. struct format_to_result {
  2517. /// Pointer to just after the last successful write in the array.
  2518. char* out;
  2519. /// Specifies if the output was truncated.
  2520. bool truncated;
  2521. FMT_CONSTEXPR operator char*() const {
  2522. // Report truncation to prevent silent data loss.
  2523. if (truncated) report_error("output is truncated");
  2524. return out;
  2525. }
  2526. };
  2527. template <size_t N>
  2528. auto vformat_to(char (&out)[N], string_view fmt, format_args args)
  2529. -> format_to_result {
  2530. auto result = vformat_to_n(out, N, fmt, args);
  2531. return {result.out, result.size > N};
  2532. }
  2533. template <size_t N, typename... T>
  2534. FMT_INLINE auto format_to(char (&out)[N], format_string<T...> fmt, T&&... args)
  2535. -> format_to_result {
  2536. auto result = vformat_to_n(out, N, fmt.str, vargs<T...>{{args...}});
  2537. return {result.out, result.size > N};
  2538. }
  2539. /// Returns the number of chars in the output of `format(fmt, args...)`.
  2540. template <typename... T>
  2541. FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
  2542. T&&... args) -> size_t {
  2543. auto buf = detail::counting_buffer<>();
  2544. detail::vformat_to(buf, fmt.str, vargs<T...>{{args...}}, {});
  2545. return buf.count();
  2546. }
  2547. FMT_API void vprint(string_view fmt, format_args args);
  2548. FMT_API void vprint(FILE* f, string_view fmt, format_args args);
  2549. FMT_API void vprintln(FILE* f, string_view fmt, format_args args);
  2550. FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args);
  2551. /**
  2552. * Formats `args` according to specifications in `fmt` and writes the output
  2553. * to `stdout`.
  2554. *
  2555. * **Example**:
  2556. *
  2557. * fmt::print("The answer is {}.", 42);
  2558. */
  2559. template <typename... T>
  2560. FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
  2561. vargs<T...> va = {{args...}};
  2562. if (detail::const_check(!detail::use_utf8))
  2563. return detail::vprint_mojibake(stdout, fmt.str, va, false);
  2564. return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt.str, va)
  2565. : vprint(fmt.str, va);
  2566. }
  2567. /**
  2568. * Formats `args` according to specifications in `fmt` and writes the
  2569. * output to the file `f`.
  2570. *
  2571. * **Example**:
  2572. *
  2573. * fmt::print(stderr, "Don't {}!", "panic");
  2574. */
  2575. template <typename... T>
  2576. FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
  2577. vargs<T...> va = {{args...}};
  2578. if (detail::const_check(!detail::use_utf8))
  2579. return detail::vprint_mojibake(f, fmt.str, va, false);
  2580. return detail::is_locking<T...>() ? vprint_buffered(f, fmt.str, va)
  2581. : vprint(f, fmt.str, va);
  2582. }
  2583. /// Formats `args` according to specifications in `fmt` and writes the output
  2584. /// to the file `f` followed by a newline.
  2585. template <typename... T>
  2586. FMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {
  2587. vargs<T...> va = {{args...}};
  2588. return detail::const_check(detail::use_utf8)
  2589. ? vprintln(f, fmt.str, va)
  2590. : detail::vprint_mojibake(f, fmt.str, va, true);
  2591. }
  2592. /// Formats `args` according to specifications in `fmt` and writes the output
  2593. /// to `stdout` followed by a newline.
  2594. template <typename... T>
  2595. FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
  2596. return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
  2597. }
  2598. FMT_END_EXPORT
  2599. FMT_PRAGMA_CLANG(diagnostic pop)
  2600. FMT_PRAGMA_GCC(pop_options)
  2601. FMT_END_NAMESPACE
  2602. #ifdef FMT_HEADER_ONLY
  2603. # include "format.h"
  2604. #endif
  2605. #endif // FMT_BASE_H_