react-native-windows 0.81.34 → 0.81.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (882) hide show
  1. package/Directory.Build.props +1 -16
  2. package/Folly/ThreadNameStub.cpp +4 -6
  3. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +1 -1
  4. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +27 -4
  5. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +8 -4
  6. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +7 -3
  7. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -7
  8. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -3
  9. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  10. package/PropertySheets/React.Cpp.props +3 -3
  11. package/ReactCommon/ReactCommon.vcxproj +0 -10
  12. package/ReactCommon/packages.lock.win32.json +0 -10
  13. package/Scripts/Tfs/Layout-Desktop-Headers.ps1 +4 -37
  14. package/Shared/Shared.vcxitems +2 -0
  15. package/{Folly → external}/.clang-format +0 -1
  16. package/external/External.vcxitems +10 -0
  17. package/external/fast-float/.syncignore +11 -0
  18. package/external/fast-float/LICENSE-APACHE +190 -0
  19. package/external/fast-float/LICENSE-BOOST +23 -0
  20. package/external/fast-float/LICENSE-MIT +27 -0
  21. package/external/fast-float/cgmanifest.json +15 -0
  22. package/external/fast-float/fast-float.vcxitems +14 -0
  23. package/external/fast-float/include/fast_float/ascii_number.h +588 -0
  24. package/external/fast-float/include/fast_float/bigint.h +638 -0
  25. package/external/fast-float/include/fast_float/constexpr_feature_detect.h +46 -0
  26. package/external/fast-float/include/fast_float/decimal_to_binary.h +212 -0
  27. package/external/fast-float/include/fast_float/digit_comparison.h +457 -0
  28. package/external/fast-float/include/fast_float/fast_float.h +59 -0
  29. package/external/fast-float/include/fast_float/fast_table.h +708 -0
  30. package/external/fast-float/include/fast_float/float_common.h +1240 -0
  31. package/external/fast-float/include/fast_float/parse_number.h +399 -0
  32. package/external/fast-float/sync-config.json +8 -0
  33. package/external/fmt/.syncignore +12 -0
  34. package/external/fmt/CONTRIBUTING.md +20 -0
  35. package/external/fmt/LICENSE +27 -0
  36. package/{fmt → external/fmt}/cgmanifest.json +1 -1
  37. package/external/fmt/fmt.vcxitems +28 -0
  38. package/external/fmt/include/fmt/args.h +228 -0
  39. package/{fmt/TEMP_UntilFmtUpdate/core.h → external/fmt/include/fmt/base.h} +1188 -1036
  40. package/external/fmt/include/fmt/chrono.h +2432 -0
  41. package/external/fmt/include/fmt/color.h +612 -0
  42. package/external/fmt/include/fmt/compile.h +529 -0
  43. package/external/fmt/include/fmt/core.h +5 -0
  44. package/external/fmt/include/fmt/format-inl.h +1928 -0
  45. package/external/fmt/include/fmt/format.h +4427 -0
  46. package/external/fmt/include/fmt/os.h +439 -0
  47. package/external/fmt/include/fmt/ostream.h +211 -0
  48. package/external/fmt/include/fmt/printf.h +656 -0
  49. package/external/fmt/include/fmt/ranges.h +882 -0
  50. package/external/fmt/include/fmt/std.h +699 -0
  51. package/external/fmt/include/fmt/xchar.h +322 -0
  52. package/external/fmt/src/fmt.cc +135 -0
  53. package/external/fmt/src/format.cc +43 -0
  54. package/external/fmt/src/os.cc +403 -0
  55. package/external/fmt/sync-config.json +8 -0
  56. package/external/folly/.syncignore +61 -0
  57. package/external/folly/LICENSE +200 -0
  58. package/{fmt → external/folly/folly}/.clang-format +0 -1
  59. package/external/folly/folly/AtomicHashArray-inl.h +546 -0
  60. package/external/folly/folly/AtomicHashArray.h +431 -0
  61. package/external/folly/folly/AtomicHashMap-inl.h +653 -0
  62. package/external/folly/folly/AtomicHashMap.h +484 -0
  63. package/external/folly/folly/AtomicIntrusiveLinkedList.h +206 -0
  64. package/external/folly/folly/AtomicLinkedList.h +110 -0
  65. package/external/folly/folly/AtomicUnorderedMap.h +522 -0
  66. package/external/folly/folly/BUCK +1631 -0
  67. package/external/folly/folly/BUILD_MODE.bzl +72 -0
  68. package/external/folly/folly/Benchmark.cpp +986 -0
  69. package/external/folly/folly/Benchmark.h +680 -0
  70. package/external/folly/folly/BenchmarkUtil.h +47 -0
  71. package/external/folly/folly/Bits.h +17 -0
  72. package/external/folly/folly/CMakeLists.txt +110 -0
  73. package/external/folly/folly/CPortability.h +338 -0
  74. package/external/folly/folly/CancellationToken-inl.h +449 -0
  75. package/external/folly/folly/CancellationToken.cpp +250 -0
  76. package/external/folly/folly/CancellationToken.h +365 -0
  77. package/external/folly/folly/Chrono.h +132 -0
  78. package/external/folly/folly/ClockGettimeWrappers.cpp +93 -0
  79. package/external/folly/folly/ClockGettimeWrappers.h +29 -0
  80. package/external/folly/folly/ConcurrentBitSet.h +157 -0
  81. package/external/folly/folly/ConcurrentLazy.h +74 -0
  82. package/external/folly/folly/ConcurrentSkipList-inl.h +341 -0
  83. package/external/folly/folly/ConcurrentSkipList.h +824 -0
  84. package/external/folly/folly/ConstructorCallbackList.h +158 -0
  85. package/external/folly/folly/Conv.h +2026 -0
  86. package/external/folly/folly/CppAttributes.h +170 -0
  87. package/external/folly/folly/CpuId.h +297 -0
  88. package/external/folly/folly/DefaultKeepAliveExecutor.h +172 -0
  89. package/external/folly/folly/Demangle.cpp +255 -0
  90. package/external/folly/folly/Demangle.h +73 -0
  91. package/external/folly/folly/DiscriminatedPtr.h +236 -0
  92. package/external/folly/folly/DynamicConverter.h +17 -0
  93. package/external/folly/folly/Exception.h +150 -0
  94. package/external/folly/folly/ExceptionString.cpp +51 -0
  95. package/external/folly/folly/ExceptionString.h +33 -0
  96. package/external/folly/folly/ExceptionWrapper-inl.h +264 -0
  97. package/external/folly/folly/ExceptionWrapper.cpp +37 -0
  98. package/external/folly/folly/ExceptionWrapper.h +377 -0
  99. package/external/folly/folly/Executor.cpp +111 -0
  100. package/external/folly/folly/Executor.h +351 -0
  101. package/external/folly/folly/Expected.h +1725 -0
  102. package/external/folly/folly/FBString.h +2888 -0
  103. package/external/folly/folly/FBVector.h +17 -0
  104. package/external/folly/folly/File.cpp +180 -0
  105. package/external/folly/folly/File.h +177 -0
  106. package/external/folly/folly/FileUtil.cpp +378 -0
  107. package/external/folly/folly/FileUtil.h +332 -0
  108. package/external/folly/folly/Fingerprint.cpp +135 -0
  109. package/external/folly/folly/Fingerprint.h +289 -0
  110. package/external/folly/folly/FixedString.h +2965 -0
  111. package/external/folly/folly/FollyMemcpy.cpp +30 -0
  112. package/external/folly/folly/FollyMemcpy.h +23 -0
  113. package/external/folly/folly/FollyMemset.cpp +29 -0
  114. package/external/folly/folly/FollyMemset.h +25 -0
  115. package/external/folly/folly/Format-inl.h +1152 -0
  116. package/external/folly/folly/Format.cpp +429 -0
  117. package/external/folly/folly/Format.h +463 -0
  118. package/external/folly/folly/FormatArg.h +285 -0
  119. package/external/folly/folly/FormatTraits.h +65 -0
  120. package/external/folly/folly/Function.h +1159 -0
  121. package/external/folly/folly/GLog.h +85 -0
  122. package/external/folly/folly/GroupVarint.cpp +153 -0
  123. package/external/folly/folly/GroupVarint.h +630 -0
  124. package/external/folly/folly/Hash.h +20 -0
  125. package/external/folly/folly/IPAddress.cpp +490 -0
  126. package/external/folly/folly/IPAddress.h +667 -0
  127. package/external/folly/folly/IPAddressException.h +82 -0
  128. package/external/folly/folly/IPAddressV4.cpp +305 -0
  129. package/external/folly/folly/IPAddressV4.h +495 -0
  130. package/external/folly/folly/IPAddressV6.cpp +541 -0
  131. package/external/folly/folly/IPAddressV6.h +627 -0
  132. package/external/folly/folly/Indestructible.h +164 -0
  133. package/external/folly/folly/IndexedMemPool.h +550 -0
  134. package/external/folly/folly/IntrusiveList.h +17 -0
  135. package/external/folly/folly/Lazy.h +142 -0
  136. package/external/folly/folly/Likely.h +76 -0
  137. package/external/folly/folly/MPMCPipeline.h +280 -0
  138. package/external/folly/folly/MPMCQueue.h +1556 -0
  139. package/external/folly/folly/MacAddress.cpp +188 -0
  140. package/external/folly/folly/MacAddress.h +260 -0
  141. package/external/folly/folly/MapUtil.h +17 -0
  142. package/external/folly/folly/Math.h +258 -0
  143. package/external/folly/folly/MaybeManagedPtr.h +120 -0
  144. package/external/folly/folly/Memory.h +900 -0
  145. package/external/folly/folly/MicroLock.cpp +76 -0
  146. package/external/folly/folly/MicroLock.h +354 -0
  147. package/external/folly/folly/MicroSpinLock.h +17 -0
  148. package/external/folly/folly/MoveWrapper.h +76 -0
  149. package/external/folly/folly/ObserverContainer.h +1026 -0
  150. package/external/folly/folly/Optional.h +743 -0
  151. package/external/folly/folly/Overload.h +325 -0
  152. package/external/folly/folly/PackedSyncPtr.h +147 -0
  153. package/external/folly/folly/Padded.h +464 -0
  154. package/external/folly/folly/Poly-inl.h +230 -0
  155. package/external/folly/folly/Poly.h +1095 -0
  156. package/external/folly/folly/PolyException.h +43 -0
  157. package/external/folly/folly/Portability.h +644 -0
  158. package/external/folly/folly/Preprocessor.h +236 -0
  159. package/external/folly/folly/ProducerConsumerQueue.h +182 -0
  160. package/external/folly/folly/RWSpinLock.h +17 -0
  161. package/external/folly/folly/Random-inl.h +86 -0
  162. package/external/folly/folly/Random.cpp +184 -0
  163. package/external/folly/folly/Random.h +434 -0
  164. package/external/folly/folly/Range.h +1772 -0
  165. package/external/folly/folly/Replaceable.h +636 -0
  166. package/external/folly/folly/ScopeGuard.cpp +29 -0
  167. package/external/folly/folly/ScopeGuard.h +420 -0
  168. package/external/folly/folly/SharedMutex.cpp +81 -0
  169. package/external/folly/folly/SharedMutex.h +1751 -0
  170. package/external/folly/folly/Singleton-inl.h +332 -0
  171. package/external/folly/folly/Singleton.cpp +512 -0
  172. package/external/folly/folly/Singleton.h +891 -0
  173. package/external/folly/folly/SingletonThreadLocal.cpp +53 -0
  174. package/external/folly/folly/SingletonThreadLocal.h +263 -0
  175. package/external/folly/folly/SocketAddress.cpp +786 -0
  176. package/external/folly/folly/SocketAddress.h +768 -0
  177. package/external/folly/folly/SpinLock.h +55 -0
  178. package/external/folly/folly/String-inl.h +668 -0
  179. package/external/folly/folly/String.cpp +777 -0
  180. package/external/folly/folly/String.h +767 -0
  181. package/external/folly/folly/Subprocess.cpp +1142 -0
  182. package/external/folly/folly/Subprocess.h +1055 -0
  183. package/external/folly/folly/Synchronized.h +1833 -0
  184. package/external/folly/folly/SynchronizedPtr.h +106 -0
  185. package/external/folly/folly/ThreadCachedInt.h +175 -0
  186. package/external/folly/folly/ThreadLocal.h +478 -0
  187. package/external/folly/folly/TimeoutQueue.cpp +78 -0
  188. package/external/folly/folly/TimeoutQueue.h +123 -0
  189. package/external/folly/folly/TokenBucket.h +673 -0
  190. package/external/folly/folly/Traits.h +1442 -0
  191. package/external/folly/folly/Try-inl.h +372 -0
  192. package/external/folly/folly/Try.cpp +23 -0
  193. package/external/folly/folly/Try.h +728 -0
  194. package/external/folly/folly/UTF8String.h +56 -0
  195. package/external/folly/folly/Unicode.cpp +201 -0
  196. package/external/folly/folly/Unicode.h +94 -0
  197. package/external/folly/folly/Unit.h +65 -0
  198. package/external/folly/folly/Uri-inl.h +101 -0
  199. package/external/folly/folly/Uri.cpp +190 -0
  200. package/external/folly/folly/Uri.h +142 -0
  201. package/external/folly/folly/Utility.h +932 -0
  202. package/external/folly/folly/VERSION +1 -0
  203. package/external/folly/folly/Varint.h +230 -0
  204. package/external/folly/folly/VirtualExecutor.h +17 -0
  205. package/external/folly/folly/algorithm/simd/BUCK +47 -0
  206. package/external/folly/folly/algorithm/simd/Contains.cpp +42 -0
  207. package/external/folly/folly/algorithm/simd/Contains.h +116 -0
  208. package/external/folly/folly/algorithm/simd/FindFixed.h +301 -0
  209. package/external/folly/folly/algorithm/simd/Ignore.h +52 -0
  210. package/external/folly/folly/algorithm/simd/Movemask.h +207 -0
  211. package/external/folly/folly/algorithm/simd/detail/BUCK +70 -0
  212. package/external/folly/folly/algorithm/simd/detail/ContainsImpl.h +91 -0
  213. package/external/folly/folly/algorithm/simd/detail/SimdAnyOf.h +83 -0
  214. package/external/folly/folly/algorithm/simd/detail/SimdForEach.h +209 -0
  215. package/external/folly/folly/algorithm/simd/detail/SimdPlatform.h +445 -0
  216. package/external/folly/folly/algorithm/simd/detail/Traits.h +125 -0
  217. package/external/folly/folly/algorithm/simd/detail/UnrollUtils.h +126 -0
  218. package/external/folly/folly/base64.h +264 -0
  219. package/external/folly/folly/chrono/BUCK +29 -0
  220. package/external/folly/folly/chrono/Clock.h +65 -0
  221. package/external/folly/folly/chrono/Conv.h +712 -0
  222. package/external/folly/folly/chrono/test/BUCK +26 -0
  223. package/external/folly/folly/chrono/test/ClockTest.cpp +68 -0
  224. package/external/folly/folly/chrono/test/ConvTest.cpp +652 -0
  225. package/external/folly/folly/concurrency/AtomicSharedPtr.h +387 -0
  226. package/external/folly/folly/concurrency/BUCK +170 -0
  227. package/external/folly/folly/concurrency/CacheLocality.h +460 -0
  228. package/external/folly/folly/concurrency/ConcurrentHashMap.h +822 -0
  229. package/external/folly/folly/concurrency/CoreCachedSharedPtr.h +232 -0
  230. package/external/folly/folly/concurrency/DeadlockDetector.cpp +27 -0
  231. package/external/folly/folly/concurrency/DeadlockDetector.h +44 -0
  232. package/external/folly/folly/concurrency/DynamicBoundedQueue.h +751 -0
  233. package/external/folly/folly/concurrency/PriorityUnboundedQueueSet.h +207 -0
  234. package/external/folly/folly/concurrency/ProcessLocalUniqueId.cpp +46 -0
  235. package/external/folly/folly/concurrency/ProcessLocalUniqueId.h +38 -0
  236. package/external/folly/folly/concurrency/SingletonRelaxedCounter.h +325 -0
  237. package/external/folly/folly/concurrency/ThreadCachedSynchronized.h +227 -0
  238. package/external/folly/folly/concurrency/UnboundedQueue.h +891 -0
  239. package/external/folly/folly/concurrency/container/BUCK +77 -0
  240. package/external/folly/folly/concurrency/container/FlatCombiningPriorityQueue.h +426 -0
  241. package/external/folly/folly/concurrency/container/LockFreeRingBuffer.h +306 -0
  242. package/external/folly/folly/concurrency/container/RelaxedConcurrentPriorityQueue.h +1212 -0
  243. package/external/folly/folly/concurrency/container/SingleWriterFixedHashMap.h +322 -0
  244. package/external/folly/folly/concurrency/container/atomic_grow_array.h +564 -0
  245. package/external/folly/folly/concurrency/container/test/BUCK +75 -0
  246. package/external/folly/folly/concurrency/container/test/FlatCombiningPriorityQueueTest.cpp +570 -0
  247. package/external/folly/folly/concurrency/container/test/LockFreeRingBufferTest.cpp +276 -0
  248. package/external/folly/folly/concurrency/container/test/RelaxedConcurrentPriorityQueueTest.cpp +1570 -0
  249. package/external/folly/folly/concurrency/container/test/SingleWriterFixedHashMapTest.cpp +401 -0
  250. package/external/folly/folly/concurrency/container/test/atomic_grow_array_test.cpp +187 -0
  251. package/external/folly/folly/concurrency/detail/AtomicSharedPtr-detail.h +212 -0
  252. package/external/folly/folly/concurrency/detail/ConcurrentHashMap-detail.h +1911 -0
  253. package/external/folly/folly/concurrency/memory/AtomicReadMostlyMainPtr.cpp +43 -0
  254. package/external/folly/folly/concurrency/memory/AtomicReadMostlyMainPtr.h +190 -0
  255. package/external/folly/folly/concurrency/memory/BUCK +53 -0
  256. package/external/folly/folly/concurrency/memory/PrimaryPtr.h +338 -0
  257. package/external/folly/folly/concurrency/memory/ReadMostlySharedPtr.h +511 -0
  258. package/external/folly/folly/concurrency/memory/TLRefCount.h +228 -0
  259. package/external/folly/folly/concurrency/memory/test/AtomicReadMostlyMainPtrBenchmark.cpp +56 -0
  260. package/external/folly/folly/concurrency/memory/test/AtomicReadMostlyMainPtrTest.cpp +454 -0
  261. package/external/folly/folly/concurrency/memory/test/BUCK +95 -0
  262. package/external/folly/folly/concurrency/memory/test/PrimaryPtrTest.cpp +303 -0
  263. package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrBenchmark.cpp +138 -0
  264. package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrStressTest.cpp +75 -0
  265. package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrTest.cpp +378 -0
  266. package/external/folly/folly/concurrency/memory/test/RefCountBenchmark.cpp +90 -0
  267. package/external/folly/folly/concurrency/memory/test/RefCountTest.cpp +168 -0
  268. package/external/folly/folly/concurrency/test/AtomicSharedPtrCounted.h +156 -0
  269. package/external/folly/folly/concurrency/test/AtomicSharedPtrPerformance.cpp +255 -0
  270. package/external/folly/folly/concurrency/test/AtomicSharedPtrTest.cpp +257 -0
  271. package/external/folly/folly/concurrency/test/BUCK +229 -0
  272. package/external/folly/folly/concurrency/test/CacheLocalityBenchmark.cpp +392 -0
  273. package/external/folly/folly/concurrency/test/CacheLocalityTest.cpp +1229 -0
  274. package/external/folly/folly/concurrency/test/ConcurrentHashMapBench.cpp +260 -0
  275. package/external/folly/folly/concurrency/test/ConcurrentHashMapTest.cpp +1242 -0
  276. package/external/folly/folly/concurrency/test/CoreCachedSharedPtrTest.cpp +408 -0
  277. package/external/folly/folly/concurrency/test/DynamicBoundedQueueTest.cpp +984 -0
  278. package/external/folly/folly/concurrency/test/PriorityUnboundedQueueSetTest.cpp +73 -0
  279. package/external/folly/folly/concurrency/test/ProcessLocalUniqueIdTest.cpp +66 -0
  280. package/external/folly/folly/concurrency/test/SingletonRelaxedCounterBench.cpp +101 -0
  281. package/external/folly/folly/concurrency/test/SingletonRelaxedCounterTest.cpp +185 -0
  282. package/external/folly/folly/concurrency/test/ThreadCachedSynchronizedBench.cpp +76 -0
  283. package/external/folly/folly/concurrency/test/ThreadCachedSynchronizedTest.cpp +93 -0
  284. package/external/folly/folly/concurrency/test/UnboundedQueueTest.cpp +1302 -0
  285. package/external/folly/folly/container/Access.h +57 -0
  286. package/external/folly/folly/container/Array.h +87 -0
  287. package/external/folly/folly/container/BUCK +353 -0
  288. package/external/folly/folly/container/BitIterator.h +203 -0
  289. package/external/folly/folly/container/Enumerate.h +162 -0
  290. package/external/folly/folly/container/EvictingCacheMap.h +730 -0
  291. package/external/folly/folly/container/F14.md +300 -0
  292. package/external/folly/folly/container/F14Map-fwd.h +113 -0
  293. package/external/folly/folly/container/F14Map.h +2108 -0
  294. package/external/folly/folly/container/F14Set-fwd.h +95 -0
  295. package/external/folly/folly/container/F14Set.h +1603 -0
  296. package/external/folly/folly/container/FBVector.h +1711 -0
  297. package/external/folly/folly/container/Foreach-inl.h +316 -0
  298. package/external/folly/folly/container/Foreach.h +209 -0
  299. package/external/folly/folly/container/HeterogeneousAccess-fwd.h +33 -0
  300. package/external/folly/folly/container/HeterogeneousAccess.h +171 -0
  301. package/external/folly/folly/container/IntrusiveHeap.h +268 -0
  302. package/external/folly/folly/container/IntrusiveList.h +131 -0
  303. package/external/folly/folly/container/Iterator.h +843 -0
  304. package/external/folly/folly/container/MapUtil.h +376 -0
  305. package/external/folly/folly/container/Merge.h +90 -0
  306. package/external/folly/folly/container/RegexMatchCache.cpp +521 -0
  307. package/external/folly/folly/container/RegexMatchCache.h +699 -0
  308. package/external/folly/folly/container/Reserve.h +109 -0
  309. package/external/folly/folly/container/SparseByteSet.h +123 -0
  310. package/external/folly/folly/container/View.h +81 -0
  311. package/external/folly/folly/container/WeightedEvictingCacheMap.h +651 -0
  312. package/external/folly/folly/container/detail/BUCK +115 -0
  313. package/external/folly/folly/container/detail/BitIteratorDetail.h +87 -0
  314. package/external/folly/folly/container/detail/F14Defaults.h +34 -0
  315. package/external/folly/folly/container/detail/F14IntrinsicsAvailability.h +67 -0
  316. package/external/folly/folly/container/detail/F14MapFallback.h +717 -0
  317. package/external/folly/folly/container/detail/F14Mask.h +235 -0
  318. package/external/folly/folly/container/detail/F14Policy.h +1523 -0
  319. package/external/folly/folly/container/detail/F14SetFallback.h +528 -0
  320. package/external/folly/folly/container/detail/F14Table.cpp +71 -0
  321. package/external/folly/folly/container/detail/F14Table.h +2680 -0
  322. package/external/folly/folly/container/detail/Util.h +303 -0
  323. package/external/folly/folly/container/detail/tape_detail.h +135 -0
  324. package/external/folly/folly/container/detail/test/BUCK +14 -0
  325. package/external/folly/folly/container/detail/test/F14DetailTest.cpp +47 -0
  326. package/external/folly/folly/container/heap_vector_types.h +1683 -0
  327. package/external/folly/folly/container/range_traits.h +81 -0
  328. package/external/folly/folly/container/small_vector.h +1476 -0
  329. package/external/folly/folly/container/sorted_vector_types.h +1652 -0
  330. package/external/folly/folly/container/span.h +408 -0
  331. package/external/folly/folly/container/tape.h +608 -0
  332. package/external/folly/folly/container/test/.clang-tidy +12 -0
  333. package/external/folly/folly/container/test/AccessTest.cpp +138 -0
  334. package/external/folly/folly/container/test/ArrayTest.cpp +84 -0
  335. package/external/folly/folly/container/test/BUCK +568 -0
  336. package/external/folly/folly/container/test/BitIteratorBench.cpp +112 -0
  337. package/external/folly/folly/container/test/BitIteratorTest.cpp +109 -0
  338. package/external/folly/folly/container/test/EnumerateTest.cpp +294 -0
  339. package/external/folly/folly/container/test/EvictingCacheMapBench.cpp +80 -0
  340. package/external/folly/folly/container/test/EvictingCacheMapTest.cpp +842 -0
  341. package/external/folly/folly/container/test/F14AsanSupportTest.cpp +143 -0
  342. package/external/folly/folly/container/test/F14FwdTest.cpp +37 -0
  343. package/external/folly/folly/container/test/F14InterprocessTest.cpp +404 -0
  344. package/external/folly/folly/container/test/F14MapTest.cpp +2543 -0
  345. package/external/folly/folly/container/test/F14PolicyTest.cpp +49 -0
  346. package/external/folly/folly/container/test/F14SetTest.cpp +1738 -0
  347. package/external/folly/folly/container/test/F14SmallOverheads.cpp +215 -0
  348. package/external/folly/folly/container/test/F14TestUtil.h +117 -0
  349. package/external/folly/folly/container/test/FBVectorBenchmark.cpp +380 -0
  350. package/external/folly/folly/container/test/FBVectorBenchmarks.cpp.h +100 -0
  351. package/external/folly/folly/container/test/FBVectorTest.cpp +326 -0
  352. package/external/folly/folly/container/test/FBVectorTests.cpp.h +304 -0
  353. package/external/folly/folly/container/test/ForeachBenchmark.cpp +388 -0
  354. package/external/folly/folly/container/test/ForeachTest.cpp +338 -0
  355. package/external/folly/folly/container/test/HashMapsBench.cpp +458 -0
  356. package/external/folly/folly/container/test/HeterogeneousAccessTest.cpp +242 -0
  357. package/external/folly/folly/container/test/IntrusiveHeapTest.cpp +262 -0
  358. package/external/folly/folly/container/test/IteratorTest.cpp +989 -0
  359. package/external/folly/folly/container/test/MapUtilTest.cpp +365 -0
  360. package/external/folly/folly/container/test/MergeTest.cpp +66 -0
  361. package/external/folly/folly/container/test/RegexMatchCacheTest.cpp +634 -0
  362. package/external/folly/folly/container/test/ReserveTest.cpp +173 -0
  363. package/external/folly/folly/container/test/SparseByteSetBenchmark.cpp +153 -0
  364. package/external/folly/folly/container/test/SparseByteSetTest.cpp +117 -0
  365. package/external/folly/folly/container/test/TrackingTypes.h +584 -0
  366. package/external/folly/folly/container/test/UtilTest.cpp +609 -0
  367. package/external/folly/folly/container/test/WeightedEvictingCacheMapTest.cpp +800 -0
  368. package/external/folly/folly/container/test/heap_vector_types_test.cpp +1774 -0
  369. package/external/folly/folly/container/test/range_traits_test.cpp +59 -0
  370. package/external/folly/folly/container/test/small_vector_test.cpp +1571 -0
  371. package/external/folly/folly/container/test/sorted_vector_test.cpp +1589 -0
  372. package/external/folly/folly/container/test/span_test.cpp +520 -0
  373. package/external/folly/folly/container/test/tape_bench.cpp +200 -0
  374. package/external/folly/folly/container/test/tape_test.cpp +590 -0
  375. package/external/folly/folly/defs.bzl +238 -0
  376. package/external/folly/folly/detail/AsyncTrace.cpp +36 -0
  377. package/external/folly/folly/detail/AsyncTrace.h +44 -0
  378. package/external/folly/folly/detail/AtomicHashUtils.h +42 -0
  379. package/external/folly/folly/detail/AtomicUnorderedMapUtils.h +80 -0
  380. package/external/folly/folly/detail/BUCK +406 -0
  381. package/external/folly/folly/detail/DiscriminatedPtrDetail.h +172 -0
  382. package/external/folly/folly/detail/FileUtilDetail.cpp +63 -0
  383. package/external/folly/folly/detail/FileUtilDetail.h +85 -0
  384. package/external/folly/folly/detail/FileUtilVectorDetail.h +81 -0
  385. package/external/folly/folly/detail/FingerprintPolynomial.h +132 -0
  386. package/external/folly/folly/detail/Futex-inl.h +123 -0
  387. package/external/folly/folly/detail/Futex.cpp +273 -0
  388. package/external/folly/folly/detail/Futex.h +109 -0
  389. package/external/folly/folly/detail/GroupVarintDetail.h +101 -0
  390. package/external/folly/folly/detail/IPAddress.cpp +37 -0
  391. package/external/folly/folly/detail/IPAddress.h +57 -0
  392. package/external/folly/folly/detail/IPAddressSource.h +278 -0
  393. package/external/folly/folly/detail/Iterators.h +156 -0
  394. package/external/folly/folly/detail/MPMCPipelineDetail.h +122 -0
  395. package/external/folly/folly/detail/MemoryIdler.cpp +233 -0
  396. package/external/folly/folly/detail/MemoryIdler.h +216 -0
  397. package/external/folly/folly/detail/PerfScoped.cpp +112 -0
  398. package/external/folly/folly/detail/PerfScoped.h +70 -0
  399. package/external/folly/folly/detail/PolyDetail.h +921 -0
  400. package/external/folly/folly/detail/RangeCommon.cpp +55 -0
  401. package/external/folly/folly/detail/RangeCommon.h +93 -0
  402. package/external/folly/folly/detail/RangeSse42.cpp +198 -0
  403. package/external/folly/folly/detail/RangeSse42.h +30 -0
  404. package/external/folly/folly/detail/SimpleSimdStringUtils.cpp +31 -0
  405. package/external/folly/folly/detail/SimpleSimdStringUtils.h +27 -0
  406. package/external/folly/folly/detail/SimpleSimdStringUtilsImpl.h +63 -0
  407. package/external/folly/folly/detail/Singleton.h +34 -0
  408. package/external/folly/folly/detail/SlowFingerprint.h +90 -0
  409. package/external/folly/folly/detail/SocketFastOpen.cpp +175 -0
  410. package/external/folly/folly/detail/SocketFastOpen.h +89 -0
  411. package/external/folly/folly/detail/SplitStringSimd.cpp +84 -0
  412. package/external/folly/folly/detail/SplitStringSimd.h +151 -0
  413. package/external/folly/folly/detail/SplitStringSimdImpl.h +149 -0
  414. package/external/folly/folly/detail/Sse.cpp +35 -0
  415. package/external/folly/folly/detail/Sse.h +45 -0
  416. package/external/folly/folly/detail/StaticSingletonManager.cpp +119 -0
  417. package/external/folly/folly/detail/StaticSingletonManager.h +298 -0
  418. package/external/folly/folly/detail/ThreadLocalDetail.cpp +492 -0
  419. package/external/folly/folly/detail/ThreadLocalDetail.h +800 -0
  420. package/external/folly/folly/detail/TrapOnAvx512.cpp +41 -0
  421. package/external/folly/folly/detail/TrapOnAvx512.h +21 -0
  422. package/external/folly/folly/detail/TurnSequencer.h +295 -0
  423. package/external/folly/folly/detail/TypeList.h +551 -0
  424. package/external/folly/folly/detail/UniqueInstance.cpp +136 -0
  425. package/external/folly/folly/detail/UniqueInstance.h +68 -0
  426. package/external/folly/folly/detail/base64_detail/BUCK +102 -0
  427. package/external/folly/folly/detail/base64_detail/Base64Api.cpp +40 -0
  428. package/external/folly/folly/detail/base64_detail/Base64Api.h +101 -0
  429. package/external/folly/folly/detail/base64_detail/Base64Common.h +80 -0
  430. package/external/folly/folly/detail/base64_detail/Base64Constants.h +79 -0
  431. package/external/folly/folly/detail/base64_detail/Base64HiddenConstants.h +129 -0
  432. package/external/folly/folly/detail/base64_detail/Base64SWAR.cpp +161 -0
  433. package/external/folly/folly/detail/base64_detail/Base64SWAR.h +32 -0
  434. package/external/folly/folly/detail/base64_detail/Base64Scalar.h +262 -0
  435. package/external/folly/folly/detail/base64_detail/Base64Simd.h +102 -0
  436. package/external/folly/folly/detail/base64_detail/Base64_SSE4_2.cpp +42 -0
  437. package/external/folly/folly/detail/base64_detail/Base64_SSE4_2.h +33 -0
  438. package/external/folly/folly/detail/base64_detail/Base64_SSE4_2_Platform.h +167 -0
  439. package/external/folly/folly/detail/base64_detail/README.md +392 -0
  440. package/external/folly/folly/detail/base64_detail/tests/BUCK +36 -0
  441. package/external/folly/folly/detail/base64_detail/tests/Base64AgainstScalarTest.cpp +141 -0
  442. package/external/folly/folly/detail/base64_detail/tests/Base64PlatformTest.cpp +273 -0
  443. package/external/folly/folly/detail/base64_detail/tests/Base64SpecialCasesTest.cpp +555 -0
  444. package/external/folly/folly/detail/test/AsyncTraceTest.cpp +43 -0
  445. package/external/folly/folly/detail/test/BUCK +118 -0
  446. package/external/folly/folly/detail/test/FileUtilDetailTest.cpp +56 -0
  447. package/external/folly/folly/detail/test/PerfScopedTest.cpp +107 -0
  448. package/external/folly/folly/detail/test/SimpleSimdStringUtilsTest.cpp +92 -0
  449. package/external/folly/folly/detail/test/SplitStringSimdTest.cpp +242 -0
  450. package/external/folly/folly/detail/test/StaticSingletonManagerTest.cpp +121 -0
  451. package/external/folly/folly/detail/test/ThreadLocalBenchmark.cpp +116 -0
  452. package/external/folly/folly/detail/test/ThreadLocalDetailTest.cpp +194 -0
  453. package/external/folly/folly/detail/test/TrapOnAvx512TestNegative.cpp +29 -0
  454. package/external/folly/folly/detail/test/UniqueInstanceTest.cpp +60 -0
  455. package/external/folly/folly/detail/thread_local_globals.cpp +69 -0
  456. package/external/folly/folly/detail/thread_local_globals.h +36 -0
  457. package/external/folly/folly/dynamic-inl.h +17 -0
  458. package/external/folly/folly/dynamic.h +17 -0
  459. package/external/folly/folly/folly_extended_library.bzl +28 -0
  460. package/external/folly/folly/functional/ApplyTuple.h +204 -0
  461. package/external/folly/folly/functional/BUCK +57 -0
  462. package/external/folly/folly/functional/Invoke.h +880 -0
  463. package/external/folly/folly/functional/Partial.h +130 -0
  464. package/external/folly/folly/functional/protocol.h +203 -0
  465. package/external/folly/folly/functional/test/ApplyTupleTest.cpp +549 -0
  466. package/external/folly/folly/functional/test/BUCK +57 -0
  467. package/external/folly/folly/functional/test/InvokeTest.cpp +483 -0
  468. package/external/folly/folly/functional/test/PartialTest.cpp +141 -0
  469. package/external/folly/folly/functional/test/protocol_test.cpp +177 -0
  470. package/external/folly/folly/functional/test/traits_test.cpp +551 -0
  471. package/external/folly/folly/functional/traits.h +675 -0
  472. package/external/folly/folly/hash/BUCK +86 -0
  473. package/external/folly/folly/hash/Checksum.cpp +275 -0
  474. package/external/folly/folly/hash/Checksum.h +94 -0
  475. package/external/folly/folly/hash/FarmHash.h +46 -0
  476. package/external/folly/folly/hash/Hash.h +1045 -0
  477. package/external/folly/folly/hash/MurmurHash.h +86 -0
  478. package/external/folly/folly/hash/SpookyHashV1.cpp +391 -0
  479. package/external/folly/folly/hash/SpookyHashV1.h +307 -0
  480. package/external/folly/folly/hash/SpookyHashV2.cpp +392 -0
  481. package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/hash/SpookyHashV2.h +6 -1
  482. package/external/folly/folly/hash/detail/BUCK +26 -0
  483. package/external/folly/folly/hash/detail/ChecksumDetail.cpp +296 -0
  484. package/external/folly/folly/hash/detail/ChecksumDetail.h +137 -0
  485. package/external/folly/folly/hash/detail/Crc32CombineDetail.cpp +191 -0
  486. package/external/folly/folly/hash/detail/Crc32cDetail.cpp +303 -0
  487. package/external/folly/folly/hash/test/BUCK +132 -0
  488. package/external/folly/folly/hash/test/ChecksumBenchmark.cpp +91 -0
  489. package/external/folly/folly/hash/test/ChecksumTest.cpp +587 -0
  490. package/external/folly/folly/hash/test/FarmHashTest.cpp +41 -0
  491. package/external/folly/folly/hash/test/HashBenchmark.cpp +238 -0
  492. package/external/folly/folly/hash/test/HashTest.cpp +997 -0
  493. package/external/folly/folly/hash/test/MurmurHashTest.cpp +76 -0
  494. package/external/folly/folly/hash/test/SpookyHashV1Test.cpp +559 -0
  495. package/external/folly/folly/hash/test/SpookyHashV2Test.cpp +549 -0
  496. package/external/folly/folly/hash/test/traits_test.cpp +69 -0
  497. package/external/folly/folly/hash/traits.h +115 -0
  498. package/external/folly/folly/json/BUCK +155 -0
  499. package/external/folly/folly/json/DynamicConverter.h +464 -0
  500. package/external/folly/folly/json/DynamicParser-inl.h +316 -0
  501. package/external/folly/folly/json/DynamicParser.cpp +198 -0
  502. package/external/folly/folly/json/DynamicParser.h +394 -0
  503. package/external/folly/folly/json/JSONSchema.cpp +1030 -0
  504. package/external/folly/folly/json/JSONSchema.h +73 -0
  505. package/external/folly/folly/json/JsonMockUtil.h +73 -0
  506. package/external/folly/folly/json/JsonTestUtil.cpp +167 -0
  507. package/external/folly/folly/json/JsonTestUtil.h +88 -0
  508. package/external/folly/folly/json/bser/BUCK +24 -0
  509. package/external/folly/folly/json/bser/Bser.h +107 -0
  510. package/external/folly/folly/json/bser/Dump.cpp +253 -0
  511. package/external/folly/folly/json/bser/Load.cpp +246 -0
  512. package/external/folly/folly/json/bser/test/BUCK +14 -0
  513. package/external/folly/folly/json/bser/test/BserTest.cpp +149 -0
  514. package/external/folly/folly/json/dynamic.cpp +552 -0
  515. package/external/folly/folly/json/dynamic.h +1346 -0
  516. package/external/folly/folly/json/json.h +238 -0
  517. package/external/folly/folly/json/json_patch.cpp +325 -0
  518. package/external/folly/folly/json/json_patch.h +126 -0
  519. package/external/folly/folly/json/json_pointer.cpp +114 -0
  520. package/external/folly/folly/json/json_pointer.h +87 -0
  521. package/external/folly/folly/json/test/BUCK +147 -0
  522. package/external/folly/folly/json/test/DynamicBenchmark.cpp +146 -0
  523. package/external/folly/folly/json/test/DynamicConverterTest.cpp +518 -0
  524. package/external/folly/folly/json/test/DynamicOtherTest.cpp +344 -0
  525. package/external/folly/folly/json/test/DynamicParserTest.cpp +443 -0
  526. package/external/folly/folly/json/test/DynamicTest.cpp +1647 -0
  527. package/external/folly/folly/json/test/JSONSchemaTest.cpp +450 -0
  528. package/external/folly/folly/json/test/JsonBenchmark.cpp +264 -0
  529. package/external/folly/folly/json/test/JsonOtherTest.cpp +51 -0
  530. package/external/folly/folly/json/test/JsonTest.cpp +1153 -0
  531. package/external/folly/folly/json/test/JsonTestUtilTest.cpp +97 -0
  532. package/external/folly/folly/json/test/json_patch_test.cpp +361 -0
  533. package/external/folly/folly/json/test/json_pointer_test.cpp +58 -0
  534. package/external/folly/folly/json/tool/BUCK +13 -0
  535. package/external/folly/folly/json/tool/JSONSchemaTester.cpp +58 -0
  536. package/external/folly/folly/json.h +17 -0
  537. package/external/folly/folly/json_patch.h +17 -0
  538. package/external/folly/folly/json_pointer.h +17 -0
  539. package/external/folly/folly/lang/Access.h +29 -0
  540. package/external/folly/folly/lang/Align.h +240 -0
  541. package/external/folly/folly/lang/Aligned.h +92 -0
  542. package/external/folly/folly/lang/Assume.h +82 -0
  543. package/external/folly/folly/lang/BUCK +287 -0
  544. package/external/folly/folly/lang/Badge.h +108 -0
  545. package/external/folly/folly/lang/Bits.h +570 -0
  546. package/external/folly/folly/lang/BitsClass.h +312 -0
  547. package/external/folly/folly/lang/Builtin.h +74 -0
  548. package/external/folly/folly/lang/CArray.h +34 -0
  549. package/external/folly/folly/lang/CString.cpp +86 -0
  550. package/external/folly/folly/lang/CString.h +55 -0
  551. package/external/folly/folly/lang/Cast.h +51 -0
  552. package/external/folly/folly/lang/CheckedMath.h +253 -0
  553. package/external/folly/folly/lang/CustomizationPoint.h +58 -0
  554. package/external/folly/folly/lang/Exception.cpp +822 -0
  555. package/external/folly/folly/lang/Exception.h +716 -0
  556. package/external/folly/folly/lang/Extern.h +55 -0
  557. package/external/folly/folly/lang/Hint-inl.h +144 -0
  558. package/external/folly/folly/lang/Hint.h +238 -0
  559. package/external/folly/folly/lang/Keep.h +98 -0
  560. package/external/folly/folly/lang/New.h +124 -0
  561. package/external/folly/folly/lang/Ordering.h +140 -0
  562. package/external/folly/folly/lang/Pretty.h +159 -0
  563. package/external/folly/folly/lang/PropagateConst.h +413 -0
  564. package/external/folly/folly/lang/RValueReferenceWrapper.h +152 -0
  565. package/external/folly/folly/lang/SafeAssert.cpp +589 -0
  566. package/external/folly/folly/lang/StaticConst.h +33 -0
  567. package/external/folly/folly/lang/Thunk.h +100 -0
  568. package/external/folly/folly/lang/TypeInfo.h +58 -0
  569. package/external/folly/folly/lang/UncaughtExceptions.cpp +17 -0
  570. package/external/folly/folly/lang/UncaughtExceptions.h +19 -0
  571. package/external/folly/folly/lang/test/AlignTest.cpp +87 -0
  572. package/external/folly/folly/lang/test/AlignedTest.cpp +130 -0
  573. package/external/folly/folly/lang/test/BUCK +258 -0
  574. package/external/folly/folly/lang/test/BadgeTest.cpp +89 -0
  575. package/external/folly/folly/lang/test/BitsBenchmark.cpp +164 -0
  576. package/external/folly/folly/lang/test/BitsClassBenchmark.cpp +122 -0
  577. package/external/folly/folly/lang/test/BitsClassTest.cpp +379 -0
  578. package/external/folly/folly/lang/test/BitsTest.cpp +577 -0
  579. package/external/folly/folly/lang/test/CStringTest.cpp +60 -0
  580. package/external/folly/folly/lang/test/CastTest.cpp +47 -0
  581. package/external/folly/folly/lang/test/CheckedMathTest.cpp +394 -0
  582. package/external/folly/folly/lang/test/ExceptionBench.cpp +427 -0
  583. package/external/folly/folly/lang/test/ExceptionTest.cpp +413 -0
  584. package/external/folly/folly/lang/test/ExternTest.cpp +39 -0
  585. package/external/folly/folly/lang/test/HintTest.cpp +100 -0
  586. package/external/folly/folly/lang/test/NewTest.cpp +38 -0
  587. package/external/folly/folly/lang/test/OrderingTest.cpp +105 -0
  588. package/external/folly/folly/lang/test/PrettyTest.cpp +44 -0
  589. package/external/folly/folly/lang/test/PropagateConstTest.cpp +356 -0
  590. package/external/folly/folly/lang/test/RValueReferenceWrapperTest.cpp +85 -0
  591. package/external/folly/folly/lang/test/SafeAssertTest.cpp +75 -0
  592. package/external/folly/folly/lang/test/ThunkTest.cpp +105 -0
  593. package/external/folly/folly/lang/test/ToAsciiBench.cpp +466 -0
  594. package/external/folly/folly/lang/test/ToAsciiTest.cpp +266 -0
  595. package/external/folly/folly/lang/test/TypeInfoTest.cpp +56 -0
  596. package/external/folly/folly/memcpy.S +292 -0
  597. package/external/folly/folly/memcpy_select_aarch64.cpp +145 -0
  598. package/external/folly/folly/memory/Arena-inl.h +83 -0
  599. package/external/folly/folly/memory/Arena.h +325 -0
  600. package/external/folly/folly/memory/BUCK +191 -0
  601. package/external/folly/folly/memory/JemallocHugePageAllocator.cpp +449 -0
  602. package/external/folly/folly/memory/JemallocHugePageAllocator.h +105 -0
  603. package/external/folly/folly/memory/JemallocHugePageAllocatorTest.cpp +341 -0
  604. package/external/folly/folly/memory/JemallocNodumpAllocator.cpp +176 -0
  605. package/external/folly/folly/memory/JemallocNodumpAllocator.h +119 -0
  606. package/external/folly/folly/memory/JemallocNodumpAllocatorTest.cpp +61 -0
  607. package/external/folly/folly/memory/MallctlHelper.cpp +37 -0
  608. package/external/folly/folly/memory/MallctlHelper.h +167 -0
  609. package/external/folly/folly/memory/Malloc.h +551 -0
  610. package/external/folly/folly/memory/MemoryResource.h +57 -0
  611. package/external/folly/folly/memory/ReentrantAllocator.cpp +162 -0
  612. package/external/folly/folly/memory/ReentrantAllocator.h +261 -0
  613. package/external/folly/folly/memory/SanitizeAddress.cpp +75 -0
  614. package/external/folly/folly/memory/SanitizeAddress.h +117 -0
  615. package/external/folly/folly/memory/SanitizeLeak.cpp +119 -0
  616. package/external/folly/folly/memory/SanitizeLeak.h +108 -0
  617. package/external/folly/folly/memory/ThreadCachedArena.cpp +53 -0
  618. package/external/folly/folly/memory/ThreadCachedArena.h +90 -0
  619. package/external/folly/folly/memory/UninitializedMemoryHacks.h +426 -0
  620. package/external/folly/folly/memory/detail/BUCK +10 -0
  621. package/external/folly/folly/memory/detail/MallocImpl.cpp +52 -0
  622. package/external/folly/folly/memory/detail/MallocImpl.h +97 -0
  623. package/external/folly/folly/memory/not_null-inl.h +522 -0
  624. package/external/folly/folly/memory/not_null.h +449 -0
  625. package/external/folly/folly/memory/test/ArenaTest.cpp +354 -0
  626. package/external/folly/folly/memory/test/BUCK +146 -0
  627. package/external/folly/folly/memory/test/MallctlHelperTest.cpp +169 -0
  628. package/external/folly/folly/memory/test/MallocBenchmark.cpp +91 -0
  629. package/external/folly/folly/memory/test/MallocTest.cpp +78 -0
  630. package/external/folly/folly/memory/test/MemoryResourceTest.cpp +31 -0
  631. package/external/folly/folly/memory/test/ReentrantAllocatorTest.cpp +144 -0
  632. package/external/folly/folly/memory/test/SanitizeAddressTest.cpp +67 -0
  633. package/external/folly/folly/memory/test/SanitizeLeakTest.cpp +139 -0
  634. package/external/folly/folly/memory/test/ThreadCachedArenaTest.cpp +276 -0
  635. package/external/folly/folly/memory/test/UninitializedMemoryHacksODR.cpp +21 -0
  636. package/external/folly/folly/memory/test/UninitializedMemoryHacksTest.cpp +327 -0
  637. package/external/folly/folly/memory/test/not_null_test.cpp +608 -0
  638. package/external/folly/folly/memset.S +245 -0
  639. package/external/folly/folly/memset_select_aarch64.cpp +72 -0
  640. package/external/folly/folly/portability/Asm.h +50 -0
  641. package/external/folly/folly/portability/Atomic.h +31 -0
  642. package/external/folly/folly/portability/BUCK +456 -0
  643. package/external/folly/folly/portability/Builtins.cpp +31 -0
  644. package/external/folly/folly/portability/Builtins.h +161 -0
  645. package/external/folly/folly/portability/Config.h +43 -0
  646. package/external/folly/folly/portability/Constexpr.h +145 -0
  647. package/external/folly/folly/portability/Dirent.cpp +140 -0
  648. package/external/folly/folly/portability/Dirent.h +41 -0
  649. package/external/folly/folly/portability/Event.h +44 -0
  650. package/external/folly/folly/portability/Fcntl.cpp +120 -0
  651. package/external/folly/folly/portability/Fcntl.h +67 -0
  652. package/external/folly/folly/portability/Filesystem.cpp +67 -0
  653. package/external/folly/folly/portability/Filesystem.h +114 -0
  654. package/external/folly/folly/portability/FmtCompile.h +40 -0
  655. package/external/folly/folly/portability/GFlags.h +139 -0
  656. package/external/folly/folly/portability/GMock.h +35 -0
  657. package/external/folly/folly/portability/GTest.h +35 -0
  658. package/external/folly/folly/portability/IOVec.h +34 -0
  659. package/external/folly/folly/portability/Libgen.cpp +59 -0
  660. package/external/folly/folly/portability/Libgen.h +29 -0
  661. package/external/folly/folly/portability/Libunwind.h +21 -0
  662. package/external/folly/folly/portability/Malloc.cpp +31 -0
  663. package/external/folly/folly/portability/Malloc.h +53 -0
  664. package/external/folly/folly/portability/Math.h +90 -0
  665. package/external/folly/folly/portability/Memory.h +26 -0
  666. package/external/folly/folly/portability/OpenSSL.cpp +17 -0
  667. package/external/folly/folly/portability/OpenSSL.h +102 -0
  668. package/external/folly/folly/portability/PThread.cpp +697 -0
  669. package/external/folly/folly/portability/PThread.h +148 -0
  670. package/external/folly/folly/portability/README.md +21 -0
  671. package/external/folly/folly/portability/Sched.cpp +41 -0
  672. package/external/folly/folly/portability/Sched.h +45 -0
  673. package/external/folly/folly/portability/Sockets.cpp +245 -0
  674. package/external/folly/folly/portability/Sockets.h +155 -0
  675. package/external/folly/folly/portability/SourceLocation.h +49 -0
  676. package/external/folly/folly/portability/Stdio.cpp +77 -0
  677. package/external/folly/folly/portability/Stdio.h +32 -0
  678. package/external/folly/folly/portability/Stdlib.cpp +172 -0
  679. package/external/folly/folly/portability/Stdlib.h +64 -0
  680. package/external/folly/folly/portability/String.cpp +53 -0
  681. package/external/folly/folly/portability/String.h +39 -0
  682. package/external/folly/folly/portability/SysFile.cpp +46 -0
  683. package/external/folly/folly/portability/SysFile.h +27 -0
  684. package/external/folly/folly/portability/SysMembarrier.cpp +104 -0
  685. package/external/folly/folly/portability/SysMembarrier.h +26 -0
  686. package/external/folly/folly/portability/SysMman.cpp +242 -0
  687. package/external/folly/folly/portability/SysMman.h +68 -0
  688. package/external/folly/folly/portability/SysResource.cpp +108 -0
  689. package/external/folly/folly/portability/SysResource.h +71 -0
  690. package/external/folly/folly/portability/SysStat.cpp +66 -0
  691. package/external/folly/folly/portability/SysStat.h +52 -0
  692. package/external/folly/folly/portability/SysSyscall.h +73 -0
  693. package/external/folly/folly/portability/SysTime.cpp +62 -0
  694. package/external/folly/folly/portability/SysTime.h +50 -0
  695. package/external/folly/folly/portability/SysTypes.h +44 -0
  696. package/external/folly/folly/portability/SysUio.cpp +179 -0
  697. package/external/folly/folly/portability/SysUio.h +51 -0
  698. package/external/folly/folly/portability/Syslog.h +39 -0
  699. package/external/folly/folly/portability/Time.cpp +357 -0
  700. package/external/folly/folly/portability/Time.h +74 -0
  701. package/external/folly/folly/portability/Unistd.h +111 -0
  702. package/external/folly/folly/portability/Windows.h +108 -0
  703. package/external/folly/folly/portability/openat2.c +30 -0
  704. package/external/folly/folly/portability/openat2.h +39 -0
  705. package/external/folly/folly/portability/test/BUCK +59 -0
  706. package/external/folly/folly/portability/test/ConstexprTest.cpp +102 -0
  707. package/external/folly/folly/portability/test/FilesystemTest.cpp +35 -0
  708. package/external/folly/folly/portability/test/LibgenTest.cpp +35 -0
  709. package/external/folly/folly/portability/test/OpenSSLPortabilityTest.cpp +108 -0
  710. package/external/folly/folly/portability/test/PThreadTest.cpp +80 -0
  711. package/external/folly/folly/portability/test/TimeTest.cpp +90 -0
  712. package/external/folly/folly/small_vector.h +17 -0
  713. package/external/folly/folly/somerge_defs.bzl +399 -0
  714. package/external/folly/folly/sorted_vector_types.h +17 -0
  715. package/external/folly/folly/stop_watch.h +317 -0
  716. package/external/folly/folly/synchronization/AsymmetricThreadFence.cpp +91 -0
  717. package/external/folly/folly/synchronization/AsymmetricThreadFence.h +60 -0
  718. package/external/folly/folly/synchronization/AtomicNotification-inl.h +146 -0
  719. package/external/folly/folly/synchronization/AtomicNotification.cpp +34 -0
  720. package/external/folly/folly/synchronization/AtomicNotification.h +117 -0
  721. package/external/folly/folly/synchronization/AtomicRef.h +181 -0
  722. package/external/folly/folly/synchronization/AtomicStruct.h +150 -0
  723. package/external/folly/folly/synchronization/AtomicUtil-inl.h +482 -0
  724. package/external/folly/folly/synchronization/AtomicUtil.h +179 -0
  725. package/external/folly/folly/synchronization/BUCK +418 -0
  726. package/external/folly/folly/synchronization/Baton.h +419 -0
  727. package/external/folly/folly/synchronization/CallOnce.h +263 -0
  728. package/external/folly/folly/synchronization/DelayedInit.h +179 -0
  729. package/external/folly/folly/synchronization/DistributedMutex-inl.h +1744 -0
  730. package/external/folly/folly/synchronization/DistributedMutex.cpp +27 -0
  731. package/external/folly/folly/synchronization/DistributedMutex.h +342 -0
  732. package/external/folly/folly/synchronization/EventCount.h +200 -0
  733. package/external/folly/folly/synchronization/FlatCombining.h +629 -0
  734. package/external/folly/folly/synchronization/Hazptr-fwd.h +217 -0
  735. package/external/folly/folly/synchronization/Hazptr.cpp +36 -0
  736. package/external/folly/folly/synchronization/Hazptr.h +209 -0
  737. package/external/folly/folly/synchronization/HazptrDomain.cpp +68 -0
  738. package/external/folly/folly/synchronization/HazptrDomain.h +832 -0
  739. package/external/folly/folly/synchronization/HazptrHolder.h +431 -0
  740. package/external/folly/folly/synchronization/HazptrObj.h +533 -0
  741. package/external/folly/folly/synchronization/HazptrObjLinked.h +315 -0
  742. package/external/folly/folly/synchronization/HazptrRec.h +68 -0
  743. package/external/folly/folly/synchronization/HazptrThrLocal.h +180 -0
  744. package/external/folly/folly/synchronization/HazptrThreadPoolExecutor.cpp +46 -0
  745. package/external/folly/folly/synchronization/HazptrThreadPoolExecutor.h +25 -0
  746. package/external/folly/folly/synchronization/Latch.h +160 -0
  747. package/external/folly/folly/synchronization/LifoSem.h +767 -0
  748. package/external/folly/folly/synchronization/Lock.h +887 -0
  749. package/external/folly/folly/synchronization/MicroSpinLock.h +154 -0
  750. package/external/folly/folly/synchronization/NativeSemaphore.h +187 -0
  751. package/external/folly/folly/synchronization/ParkingLot.cpp +37 -0
  752. package/external/folly/folly/synchronization/ParkingLot.h +330 -0
  753. package/external/folly/folly/synchronization/PicoSpinLock.h +167 -0
  754. package/external/folly/folly/synchronization/RWSpinLock.h +549 -0
  755. package/external/folly/folly/synchronization/Rcu.cpp +26 -0
  756. package/external/folly/folly/synchronization/Rcu.h +553 -0
  757. package/external/folly/folly/synchronization/RelaxedAtomic.h +336 -0
  758. package/external/folly/folly/synchronization/SanitizeThread.cpp +141 -0
  759. package/external/folly/folly/synchronization/SanitizeThread.h +166 -0
  760. package/external/folly/folly/synchronization/SaturatingSemaphore.h +324 -0
  761. package/external/folly/folly/synchronization/SmallLocks.h +36 -0
  762. package/external/folly/folly/synchronization/ThrottledLifoSem.h +362 -0
  763. package/external/folly/folly/synchronization/WaitOptions.cpp +25 -0
  764. package/external/folly/folly/synchronization/WaitOptions.h +75 -0
  765. package/external/folly/folly/synchronization/detail/AtomicUtils.h +59 -0
  766. package/external/folly/folly/synchronization/detail/BUCK +104 -0
  767. package/external/folly/folly/synchronization/detail/Hardware.cpp +192 -0
  768. package/external/folly/folly/synchronization/detail/Hardware.h +75 -0
  769. package/external/folly/folly/synchronization/detail/HazptrUtils.h +339 -0
  770. package/external/folly/folly/synchronization/detail/InlineFunctionRef.h +229 -0
  771. package/external/folly/folly/synchronization/detail/Sleeper.cpp +27 -0
  772. package/external/folly/folly/synchronization/detail/Sleeper.h +62 -0
  773. package/external/folly/folly/synchronization/detail/Spin.h +96 -0
  774. package/external/folly/folly/synchronization/detail/ThreadCachedLists.h +174 -0
  775. package/external/folly/folly/synchronization/detail/ThreadCachedReaders.h +189 -0
  776. package/external/folly/folly/synchronization/detail/ThreadCachedTag.h +26 -0
  777. package/external/folly/folly/synchronization/detail/test/BUCK +28 -0
  778. package/external/folly/folly/synchronization/detail/test/HardwareTest.cpp +74 -0
  779. package/external/folly/folly/synchronization/detail/test/InlineFunctionRefTest.cpp +286 -0
  780. package/external/folly/folly/synchronization/example/BUCK +27 -0
  781. package/external/folly/folly/synchronization/example/HazptrLockFreeLIFO.h +88 -0
  782. package/external/folly/folly/synchronization/example/HazptrSWMRSet.h +133 -0
  783. package/external/folly/folly/synchronization/example/HazptrWideCAS.h +62 -0
  784. package/external/folly/folly/synchronization/test/AtomicNotificationTest.cpp +236 -0
  785. package/external/folly/folly/synchronization/test/AtomicRefTest.cpp +170 -0
  786. package/external/folly/folly/synchronization/test/AtomicStructTest.cpp +65 -0
  787. package/external/folly/folly/synchronization/test/AtomicUtilBench.cpp +457 -0
  788. package/external/folly/folly/synchronization/test/AtomicUtilTest.cpp +650 -0
  789. package/external/folly/folly/synchronization/test/BUCK +495 -0
  790. package/external/folly/folly/synchronization/test/Barrier.h +52 -0
  791. package/external/folly/folly/synchronization/test/BarrierTest.cpp +56 -0
  792. package/external/folly/folly/synchronization/test/BatonBenchmark.cpp +77 -0
  793. package/external/folly/folly/synchronization/test/BatonTest.cpp +164 -0
  794. package/external/folly/folly/synchronization/test/BatonTestHelpers.h +118 -0
  795. package/external/folly/folly/synchronization/test/CallOnceBenchmark.cpp +72 -0
  796. package/external/folly/folly/synchronization/test/CallOnceTest.cpp +153 -0
  797. package/external/folly/folly/synchronization/test/DelayedInitTest.cpp +281 -0
  798. package/external/folly/folly/synchronization/test/DistributedMutexTest.cpp +2074 -0
  799. package/external/folly/folly/synchronization/test/EventCountTest.cpp +124 -0
  800. package/external/folly/folly/synchronization/test/FlatCombiningBenchmark.cpp +1789 -0
  801. package/external/folly/folly/synchronization/test/FlatCombiningExamples.h +222 -0
  802. package/external/folly/folly/synchronization/test/FlatCombiningTest.cpp +121 -0
  803. package/external/folly/folly/synchronization/test/FlatCombiningTestHelpers.h +227 -0
  804. package/external/folly/folly/synchronization/test/HazptrTest.cpp +1689 -0
  805. package/external/folly/folly/synchronization/test/LatchTest.cpp +224 -0
  806. package/external/folly/folly/synchronization/test/LifoSemBench.cpp +185 -0
  807. package/external/folly/folly/synchronization/test/LifoSemTests.cpp +353 -0
  808. package/external/folly/folly/synchronization/test/LockTest.cpp +1239 -0
  809. package/external/folly/folly/synchronization/test/NativeSemaphoreTest.cpp +37 -0
  810. package/external/folly/folly/synchronization/test/ParkingLotBenchmark.cpp +239 -0
  811. package/external/folly/folly/synchronization/test/ParkingLotTest.cpp +170 -0
  812. package/external/folly/folly/synchronization/test/RWSpinLockTest.cpp +235 -0
  813. package/external/folly/folly/synchronization/test/RcuBench.cpp +66 -0
  814. package/external/folly/folly/synchronization/test/RcuTest.cpp +330 -0
  815. package/external/folly/folly/synchronization/test/RelaxedAtomicTest.cpp +389 -0
  816. package/external/folly/folly/synchronization/test/SaturatingSemaphoreTest.cpp +166 -0
  817. package/external/folly/folly/synchronization/test/Semaphore.h +242 -0
  818. package/external/folly/folly/synchronization/test/SemaphoreTest.cpp +271 -0
  819. package/external/folly/folly/synchronization/test/SmallLocksBenchmark.cpp +1296 -0
  820. package/external/folly/folly/synchronization/test/SmallLocksTest.cpp +510 -0
  821. package/external/folly/folly/synchronization/test/ThreadCachedEpochBench.h +67 -0
  822. package/external/folly/folly/synchronization/test/ThreadCachedReadersBench.cpp +42 -0
  823. package/external/folly/folly/synchronization/test/ThreadCachedReadersTest.cpp +52 -0
  824. package/external/folly/folly/synchronization/test/ThrottledLifoSemTest.cpp +243 -0
  825. package/external/folly/folly/system/AtFork.cpp +205 -0
  826. package/external/folly/folly/system/AtFork.h +116 -0
  827. package/external/folly/folly/system/AuxVector.h +198 -0
  828. package/external/folly/folly/system/BUCK +144 -0
  829. package/external/folly/folly/system/EnvUtil.cpp +93 -0
  830. package/external/folly/folly/system/EnvUtil.h +113 -0
  831. package/external/folly/folly/system/HardwareConcurrency.cpp +39 -0
  832. package/external/folly/folly/system/HardwareConcurrency.h +23 -0
  833. package/external/folly/folly/system/MemoryMapping.cpp +477 -0
  834. package/external/folly/folly/system/MemoryMapping.h +287 -0
  835. package/external/folly/folly/system/Pid.cpp +87 -0
  836. package/external/folly/folly/system/Pid.h +34 -0
  837. package/external/folly/folly/system/Shell.cpp +33 -0
  838. package/external/folly/folly/system/Shell.h +93 -0
  839. package/external/folly/folly/system/ThreadId.cpp +89 -0
  840. package/external/folly/folly/system/ThreadId.h +62 -0
  841. package/external/folly/folly/system/ThreadName.cpp +330 -0
  842. package/external/folly/folly/system/ThreadName.h +72 -0
  843. package/external/folly/folly/system/test/AtForkTest.cpp +309 -0
  844. package/external/folly/folly/system/test/AuxVectorTest.cpp +55 -0
  845. package/external/folly/folly/system/test/BUCK +120 -0
  846. package/external/folly/folly/system/test/EnvUtilSubprocess.cpp +26 -0
  847. package/external/folly/folly/system/test/EnvUtilTest.cpp +197 -0
  848. package/external/folly/folly/system/test/MemoryMappingTest.cpp +179 -0
  849. package/external/folly/folly/system/test/PidTest.cpp +46 -0
  850. package/external/folly/folly/system/test/ShellTest.cpp +66 -0
  851. package/external/folly/folly/system/test/ThreadIdTest.cpp +114 -0
  852. package/external/folly/folly/system/test/ThreadNameTest.cpp +85 -0
  853. package/external/folly/folly.vcxitems +164 -0
  854. package/external/folly/sync-config.json +8 -0
  855. package/package.json +3 -3
  856. package/template/cpp-app/proj/MyApp.sln +0 -33
  857. package/template/cpp-lib/proj/MyLib.sln +0 -33
  858. package/template/cs-app/proj/MyApp.sln +0 -33
  859. package/template/cs-lib/proj/MyLib.sln +0 -33
  860. package/templates/cpp-app/windows/MyApp.sln +0 -33
  861. package/templates/cpp-lib/windows/MyLib.sln +0 -33
  862. package/Folly/Folly.vcxproj +0 -383
  863. package/Folly/Folly.vcxproj.filters +0 -558
  864. package/Folly/Folly.win32.vcxproj +0 -11
  865. package/Folly/packages.lock.win32.json +0 -20
  866. package/fmt/fmt.vcxproj +0 -163
  867. package/fmt/fmt.vcxproj.filters +0 -59
  868. package/fmt/fmt.win32.vcxproj +0 -10
  869. package/fmt/pch.cpp +0 -4
  870. package/fmt/pch.h +0 -2
  871. /package/{Folly → external/folly}/Folly.natvis +0 -0
  872. /package/{Folly → external/folly}/cgmanifest.json +0 -0
  873. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/ConstexprMath.h +0 -0
  874. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/Conv.cpp +0 -0
  875. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/chrono/Hardware.h +0 -0
  876. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/concurrency/CacheLocality.cpp +0 -0
  877. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/json/dynamic-inl.h +0 -0
  878. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/json/json.cpp +0 -0
  879. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/SafeAssert.h +0 -0
  880. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/ToAscii.cpp +0 -0
  881. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/ToAscii.h +0 -0
  882. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/portability/Unistd.cpp +0 -0
@@ -1,61 +1,64 @@
1
- // Formatting library for C++ - the core API for char/UTF-8
1
+ // Formatting library for C++ - the base API for char/UTF-8
2
2
  //
3
3
  // Copyright (c) 2012 - present, Victor Zverovich
4
4
  // All rights reserved.
5
5
  //
6
6
  // For the license information refer to format.h.
7
7
 
8
- #ifndef FMT_CORE_H_
9
- #define FMT_CORE_H_
8
+ #ifndef FMT_BASE_H_
9
+ #define FMT_BASE_H_
10
10
 
11
- #include <cstddef> // std::byte
12
- #include <cstdio> // std::FILE
13
- #include <cstring> // std::strlen
14
- #include <iterator>
15
- #include <limits>
16
- #include <memory> // std::addressof
17
- #include <string>
18
- #include <type_traits>
11
+ #if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE)
12
+ # define FMT_MODULE
13
+ #endif
14
+
15
+ #ifndef FMT_MODULE
16
+ # include <limits.h> // CHAR_BIT
17
+ # include <stdio.h> // FILE
18
+ # include <string.h> // strlen
19
+
20
+ // <cstddef> is also included transitively from <type_traits>.
21
+ # include <cstddef> // std::byte
22
+ # include <type_traits> // std::enable_if
23
+ #endif
19
24
 
20
25
  // The fmt library version in the form major * 10000 + minor * 100 + patch.
21
- #define FMT_VERSION 100100
26
+ #define FMT_VERSION 110002
22
27
 
28
+ // Detect compiler versions.
23
29
  #if defined(__clang__) && !defined(__ibmxl__)
24
30
  # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
25
31
  #else
26
32
  # define FMT_CLANG_VERSION 0
27
33
  #endif
28
-
29
- #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && \
30
- !defined(__NVCOMPILER)
34
+ #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
31
35
  # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
32
36
  #else
33
37
  # define FMT_GCC_VERSION 0
34
38
  #endif
35
-
36
- #ifndef FMT_GCC_PRAGMA
37
- // Workaround _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884.
38
- # if FMT_GCC_VERSION >= 504
39
- # define FMT_GCC_PRAGMA(arg) _Pragma(arg)
40
- # else
41
- # define FMT_GCC_PRAGMA(arg)
42
- # endif
43
- #endif
44
-
45
- #ifdef __ICL
39
+ #if defined(__ICL)
46
40
  # define FMT_ICC_VERSION __ICL
47
41
  #elif defined(__INTEL_COMPILER)
48
42
  # define FMT_ICC_VERSION __INTEL_COMPILER
49
43
  #else
50
44
  # define FMT_ICC_VERSION 0
51
45
  #endif
52
-
53
- #ifdef _MSC_VER
46
+ #if defined(_MSC_VER)
54
47
  # define FMT_MSC_VERSION _MSC_VER
55
- # define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
56
48
  #else
57
49
  # define FMT_MSC_VERSION 0
58
- # define FMT_MSC_WARNING(...)
50
+ #endif
51
+
52
+ // Detect standard library versions.
53
+ #ifdef _GLIBCXX_RELEASE
54
+ # define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE
55
+ #else
56
+ # define FMT_GLIBCXX_RELEASE 0
57
+ #endif
58
+ #ifdef _LIBCPP_VERSION
59
+ # define FMT_LIBCPP_VERSION _LIBCPP_VERSION
60
+ #else
61
+ # define FMT_LIBCPP_VERSION 0
59
62
  #endif
60
63
 
61
64
  #ifdef _MSVC_LANG
@@ -64,18 +67,17 @@
64
67
  # define FMT_CPLUSPLUS __cplusplus
65
68
  #endif
66
69
 
70
+ // Detect __has_*.
67
71
  #ifdef __has_feature
68
72
  # define FMT_HAS_FEATURE(x) __has_feature(x)
69
73
  #else
70
74
  # define FMT_HAS_FEATURE(x) 0
71
75
  #endif
72
-
73
- #if defined(__has_include) || FMT_ICC_VERSION >= 1600 || FMT_MSC_VERSION > 1900
76
+ #ifdef __has_include
74
77
  # define FMT_HAS_INCLUDE(x) __has_include(x)
75
78
  #else
76
79
  # define FMT_HAS_INCLUDE(x) 0
77
80
  #endif
78
-
79
81
  #ifdef __has_cpp_attribute
80
82
  # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
81
83
  #else
@@ -88,16 +90,19 @@
88
90
  #define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
89
91
  (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
90
92
 
91
- // Check if relaxed C++14 constexpr is supported.
92
- // GCC doesn't allow throw in constexpr until version 6 (bug 67371).
93
- #ifndef FMT_USE_CONSTEXPR
94
- # if (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912 || \
95
- (FMT_GCC_VERSION >= 600 && FMT_CPLUSPLUS >= 201402L)) && \
96
- !FMT_ICC_VERSION && (!defined(__NVCC__) || FMT_CPLUSPLUS >= 202002L)
97
- # define FMT_USE_CONSTEXPR 1
98
- # else
99
- # define FMT_USE_CONSTEXPR 0
100
- # endif
93
+ // Detect C++14 relaxed constexpr.
94
+ #ifdef FMT_USE_CONSTEXPR
95
+ // Use the provided definition.
96
+ #elif FMT_GCC_VERSION >= 600 && FMT_CPLUSPLUS >= 201402L
97
+ // GCC only allows throw in constexpr since version 6:
98
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371.
99
+ # define FMT_USE_CONSTEXPR 1
100
+ #elif FMT_ICC_VERSION
101
+ # define FMT_USE_CONSTEXPR 0 // https://github.com/fmtlib/fmt/issues/1628
102
+ #elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912
103
+ # define FMT_USE_CONSTEXPR 1
104
+ #else
105
+ # define FMT_USE_CONSTEXPR 0
101
106
  #endif
102
107
  #if FMT_USE_CONSTEXPR
103
108
  # define FMT_CONSTEXPR constexpr
@@ -105,43 +110,88 @@
105
110
  # define FMT_CONSTEXPR
106
111
  #endif
107
112
 
108
- #if ((FMT_CPLUSPLUS >= 202002L) && \
109
- (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9)) || \
110
- (FMT_CPLUSPLUS >= 201709L && FMT_GCC_VERSION >= 1002)
113
+ // Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated.
114
+ #if !defined(__cpp_lib_is_constant_evaluated)
115
+ # define FMT_USE_CONSTEVAL 0
116
+ #elif FMT_CPLUSPLUS < 201709L
117
+ # define FMT_USE_CONSTEVAL 0
118
+ #elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10
119
+ # define FMT_USE_CONSTEVAL 0
120
+ #elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000
121
+ # define FMT_USE_CONSTEVAL 0
122
+ #elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L
123
+ # define FMT_USE_CONSTEVAL 0 // consteval is broken in Apple clang < 14.
124
+ #elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929
125
+ # define FMT_USE_CONSTEVAL 0 // consteval is broken in MSVC VS2019 < 16.10.
126
+ #elif defined(__cpp_consteval)
127
+ # define FMT_USE_CONSTEVAL 1
128
+ #elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101
129
+ # define FMT_USE_CONSTEVAL 1
130
+ #else
131
+ # define FMT_USE_CONSTEVAL 0
132
+ #endif
133
+ #if FMT_USE_CONSTEVAL
134
+ # define FMT_CONSTEVAL consteval
111
135
  # define FMT_CONSTEXPR20 constexpr
112
136
  #else
137
+ # define FMT_CONSTEVAL
113
138
  # define FMT_CONSTEXPR20
114
139
  #endif
115
140
 
116
- // Check if constexpr std::char_traits<>::{compare,length} are supported.
117
- #if defined(__GLIBCXX__)
118
- # if FMT_CPLUSPLUS >= 201703L && defined(_GLIBCXX_RELEASE) && \
119
- _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE.
120
- # define FMT_CONSTEXPR_CHAR_TRAITS constexpr
121
- # endif
122
- #elif defined(_LIBCPP_VERSION) && FMT_CPLUSPLUS >= 201703L && \
123
- _LIBCPP_VERSION >= 4000
124
- # define FMT_CONSTEXPR_CHAR_TRAITS constexpr
125
- #elif FMT_MSC_VERSION >= 1914 && FMT_CPLUSPLUS >= 201703L
126
- # define FMT_CONSTEXPR_CHAR_TRAITS constexpr
141
+ #if defined(FMT_USE_NONTYPE_TEMPLATE_ARGS)
142
+ // Use the provided definition.
143
+ #elif defined(__NVCOMPILER)
144
+ # define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
145
+ #elif FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L
146
+ # define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
147
+ #elif defined(__cpp_nontype_template_args) && \
148
+ __cpp_nontype_template_args >= 201911L
149
+ # define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
150
+ #elif FMT_CLANG_VERSION >= 1200 && FMT_CPLUSPLUS >= 202002L
151
+ # define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
152
+ #else
153
+ # define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
127
154
  #endif
128
- #ifndef FMT_CONSTEXPR_CHAR_TRAITS
129
- # define FMT_CONSTEXPR_CHAR_TRAITS
155
+
156
+ #ifdef FMT_USE_CONCEPTS
157
+ // Use the provided definition.
158
+ #elif defined(__cpp_concepts)
159
+ # define FMT_USE_CONCEPTS 1
160
+ #else
161
+ # define FMT_USE_CONCEPTS 0
130
162
  #endif
131
163
 
132
164
  // Check if exceptions are disabled.
133
- #ifndef FMT_EXCEPTIONS
134
- # if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
135
- (FMT_MSC_VERSION && !_HAS_EXCEPTIONS)
136
- # define FMT_EXCEPTIONS 0
137
- # else
138
- # define FMT_EXCEPTIONS 1
139
- # endif
165
+ #ifdef FMT_EXCEPTIONS
166
+ // Use the provided definition.
167
+ #elif defined(__GNUC__) && !defined(__EXCEPTIONS)
168
+ # define FMT_EXCEPTIONS 0
169
+ #elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
170
+ # define FMT_EXCEPTIONS 0
171
+ #else
172
+ # define FMT_EXCEPTIONS 1
173
+ #endif
174
+ #if FMT_EXCEPTIONS
175
+ # define FMT_TRY try
176
+ # define FMT_CATCH(x) catch (x)
177
+ #else
178
+ # define FMT_TRY if (true)
179
+ # define FMT_CATCH(x) if (false)
180
+ #endif
181
+
182
+ #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
183
+ # define FMT_FALLTHROUGH [[fallthrough]]
184
+ #elif defined(__clang__)
185
+ # define FMT_FALLTHROUGH [[clang::fallthrough]]
186
+ #elif FMT_GCC_VERSION >= 700 && \
187
+ (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
188
+ # define FMT_FALLTHROUGH [[gnu::fallthrough]]
189
+ #else
190
+ # define FMT_FALLTHROUGH
140
191
  #endif
141
192
 
142
193
  // Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
143
- #if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && \
144
- !defined(__NVCC__)
194
+ #if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__)
145
195
  # define FMT_NORETURN [[noreturn]]
146
196
  #else
147
197
  # define FMT_NORETURN
@@ -155,25 +205,64 @@
155
205
  # endif
156
206
  #endif
157
207
 
158
- #ifndef FMT_INLINE
159
- # if FMT_GCC_VERSION || FMT_CLANG_VERSION
160
- # define FMT_INLINE inline __attribute__((always_inline))
208
+ #ifdef FMT_DEPRECATED
209
+ // Use the provided definition.
210
+ #elif FMT_HAS_CPP14_ATTRIBUTE(deprecated)
211
+ # define FMT_DEPRECATED [[deprecated]]
212
+ #else
213
+ # define FMT_DEPRECATED /* deprecated */
214
+ #endif
215
+
216
+ #ifdef FMT_INLINE
217
+ // Use the provided definition.
218
+ #elif FMT_GCC_VERSION || FMT_CLANG_VERSION
219
+ # define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
220
+ #else
221
+ # define FMT_ALWAYS_INLINE inline
222
+ #endif
223
+ // A version of FMT_INLINE to prevent code bloat in debug mode.
224
+ #ifdef NDEBUG
225
+ # define FMT_INLINE FMT_ALWAYS_INLINE
226
+ #else
227
+ # define FMT_INLINE inline
228
+ #endif
229
+
230
+ #if FMT_GCC_VERSION || FMT_CLANG_VERSION
231
+ # define FMT_VISIBILITY(value) __attribute__((visibility(value)))
232
+ #else
233
+ # define FMT_VISIBILITY(value)
234
+ #endif
235
+
236
+ #ifndef FMT_GCC_PRAGMA
237
+ // Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884
238
+ // and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582.
239
+ # if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER)
240
+ # define FMT_GCC_PRAGMA(arg) _Pragma(arg)
161
241
  # else
162
- # define FMT_INLINE inline
242
+ # define FMT_GCC_PRAGMA(arg)
163
243
  # endif
164
244
  #endif
165
245
 
166
- #ifdef _MSC_VER
246
+ // GCC < 5 requires this-> in decltype.
247
+ #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
248
+ # define FMT_DECLTYPE_THIS this->
249
+ #else
250
+ # define FMT_DECLTYPE_THIS
251
+ #endif
252
+
253
+ #if FMT_MSC_VERSION
254
+ # define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
167
255
  # define FMT_UNCHECKED_ITERATOR(It) \
168
256
  using _Unchecked_type = It // Mark iterator as checked.
169
257
  #else
258
+ # define FMT_MSC_WARNING(...)
170
259
  # define FMT_UNCHECKED_ITERATOR(It) using unchecked_type = It
171
260
  #endif
172
261
 
173
262
  #ifndef FMT_BEGIN_NAMESPACE
174
263
  # define FMT_BEGIN_NAMESPACE \
175
264
  namespace fmt { \
176
- inline namespace v10 {
265
+ inline namespace v11 {
177
266
  # define FMT_END_NAMESPACE \
178
267
  } \
179
268
  }
@@ -186,66 +275,38 @@
186
275
  #endif
187
276
 
188
277
  #if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
189
- # ifdef FMT_LIB_EXPORT
278
+ # if defined(FMT_LIB_EXPORT)
190
279
  # define FMT_API __declspec(dllexport)
191
280
  # elif defined(FMT_SHARED)
192
281
  # define FMT_API __declspec(dllimport)
193
282
  # endif
194
- #else
195
- # if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
196
- # if defined(__GNUC__) || defined(__clang__)
197
- # define FMT_API __attribute__((visibility("default")))
198
- # endif
199
- # endif
283
+ #elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
284
+ # define FMT_API FMT_VISIBILITY("default")
200
285
  #endif
201
286
  #ifndef FMT_API
202
287
  # define FMT_API
203
288
  #endif
204
289
 
205
- // libc++ supports string_view in pre-c++17.
206
- #if FMT_HAS_INCLUDE(<string_view>) && \
207
- (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))
208
- # include <string_view>
209
- # define FMT_USE_STRING_VIEW
210
- #elif FMT_HAS_INCLUDE("experimental/string_view") && FMT_CPLUSPLUS >= 201402L
211
- # include <experimental/string_view>
212
- # define FMT_USE_EXPERIMENTAL_STRING_VIEW
213
- #endif
214
-
215
290
  #ifndef FMT_UNICODE
216
- # define FMT_UNICODE !FMT_MSC_VERSION
291
+ # define FMT_UNICODE 1
217
292
  #endif
218
293
 
219
- #ifndef FMT_CONSTEVAL
220
- # if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \
221
- (!defined(__apple_build_version__) || \
222
- __apple_build_version__ >= 14000029L) && \
223
- FMT_CPLUSPLUS >= 202002L) || \
224
- (defined(__cpp_consteval) && \
225
- (!FMT_MSC_VERSION || _MSC_FULL_VER >= 193030704))
226
- // consteval is broken in MSVC before VS2022 and Apple clang before 14.
227
- # define FMT_CONSTEVAL consteval
228
- # define FMT_HAS_CONSTEVAL
294
+ // Check if rtti is available.
295
+ #ifndef FMT_USE_RTTI
296
+ // __RTTI is for EDG compilers. _CPPRTTI is for MSVC.
297
+ # if defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || defined(_CPPRTTI) || \
298
+ defined(__INTEL_RTTI__) || defined(__RTTI)
299
+ # define FMT_USE_RTTI 1
229
300
  # else
230
- # define FMT_CONSTEVAL
301
+ # define FMT_USE_RTTI 0
231
302
  # endif
232
303
  #endif
233
304
 
234
- #ifndef FMT_USE_NONTYPE_TEMPLATE_ARGS
235
- # if defined(__cpp_nontype_template_args) && \
236
- ((FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L) || \
237
- __cpp_nontype_template_args >= 201911L) && \
238
- !defined(__NVCOMPILER) && !defined(__LCC__)
239
- # define FMT_USE_NONTYPE_TEMPLATE_ARGS 1
240
- # else
241
- # define FMT_USE_NONTYPE_TEMPLATE_ARGS 0
242
- # endif
243
- #endif
305
+ #define FMT_FWD(...) static_cast<decltype(__VA_ARGS__)&&>(__VA_ARGS__)
244
306
 
245
307
  // Enable minimal optimizations for more compact code in debug mode.
246
308
  FMT_GCC_PRAGMA("GCC push_options")
247
- #if !defined(__OPTIMIZE__) && !defined(__NVCOMPILER) && !defined(__LCC__) && \
248
- !defined(__CUDACC__)
309
+ #if !defined(__OPTIMIZE__) && !defined(__CUDACC__)
249
310
  FMT_GCC_PRAGMA("GCC optimize(\"Og\")")
250
311
  #endif
251
312
 
@@ -263,15 +324,24 @@ template <typename T>
263
324
  using remove_const_t = typename std::remove_const<T>::type;
264
325
  template <typename T>
265
326
  using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
266
- template <typename T> struct type_identity { using type = T; };
327
+ template <typename T> struct type_identity {
328
+ using type = T;
329
+ };
267
330
  template <typename T> using type_identity_t = typename type_identity<T>::type;
268
331
  template <typename T>
332
+ using make_unsigned_t = typename std::make_unsigned<T>::type;
333
+ template <typename T>
269
334
  using underlying_t = typename std::underlying_type<T>::type;
270
335
 
271
- // Checks whether T is a container with contiguous storage.
272
- template <typename T> struct is_contiguous : std::false_type {};
273
- template <typename Char>
274
- struct is_contiguous<std::basic_string<Char>> : std::true_type {};
336
+ #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
337
+ // A workaround for gcc 4.8 to make void_t work in a SFINAE context.
338
+ template <typename...> struct void_t_impl {
339
+ using type = void;
340
+ };
341
+ template <typename... T> using void_t = typename void_t_impl<T...>::type;
342
+ #else
343
+ template <typename...> using void_t = void;
344
+ #endif
275
345
 
276
346
  struct monostate {
277
347
  constexpr monostate() {}
@@ -286,7 +356,7 @@ struct monostate {
286
356
  # define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
287
357
  #endif
288
358
 
289
- // This is defined in core.h instead of format.h to avoid injecting in std.
359
+ // This is defined in base.h instead of format.h to avoid injecting in std.
290
360
  // It is a template to avoid undesirable implicit conversions to std::byte.
291
361
  #ifdef __cpp_lib_byte
292
362
  template <typename T, FMT_ENABLE_IF(std::is_same<T, std::byte>::value)>
@@ -301,13 +371,12 @@ namespace detail {
301
371
  // (void)var does not work on many Intel compilers.
302
372
  template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}
303
373
 
304
- constexpr FMT_INLINE auto is_constant_evaluated(
305
- bool default_value = false) noexcept -> bool {
374
+ constexpr auto is_constant_evaluated(bool default_value = false) noexcept
375
+ -> bool {
306
376
  // Workaround for incompatibility between libstdc++ consteval-based
307
- // std::is_constant_evaluated() implementation and clang-14.
308
- // https://github.com/fmtlib/fmt/issues/3247
309
- #if FMT_CPLUSPLUS >= 202002L && defined(_GLIBCXX_RELEASE) && \
310
- _GLIBCXX_RELEASE >= 12 && \
377
+ // std::is_constant_evaluated() implementation and clang-14:
378
+ // https://github.com/fmtlib/fmt/issues/3247.
379
+ #if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \
311
380
  (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500)
312
381
  ignore_unused(default_value);
313
382
  return __builtin_is_constant_evaluated();
@@ -320,33 +389,22 @@ constexpr FMT_INLINE auto is_constant_evaluated(
320
389
  }
321
390
 
322
391
  // Suppresses "conditional expression is constant" warnings.
323
- template <typename T> constexpr FMT_INLINE auto const_check(T value) -> T {
324
- return value;
325
- }
392
+ template <typename T> constexpr auto const_check(T value) -> T { return value; }
326
393
 
327
394
  FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
328
395
  const char* message);
329
396
 
330
- #ifndef FMT_ASSERT
331
- # ifdef NDEBUG
397
+ #if defined(FMT_ASSERT)
398
+ // Use the provided definition.
399
+ #elif defined(NDEBUG)
332
400
  // FMT_ASSERT is not empty to avoid -Wempty-body.
333
- # define FMT_ASSERT(condition, message) \
334
- fmt::detail::ignore_unused((condition), (message))
335
- # else
336
- # define FMT_ASSERT(condition, message) \
337
- ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
338
- ? (void)0 \
339
- : fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
340
- # endif
341
- #endif
342
-
343
- #if defined(FMT_USE_STRING_VIEW)
344
- template <typename Char> using std_string_view = std::basic_string_view<Char>;
345
- #elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
346
- template <typename Char>
347
- using std_string_view = std::experimental::basic_string_view<Char>;
401
+ # define FMT_ASSERT(condition, message) \
402
+ fmt::detail::ignore_unused((condition), (message))
348
403
  #else
349
- template <typename T> struct std_string_view {};
404
+ # define FMT_ASSERT(condition, message) \
405
+ ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
406
+ ? (void)0 \
407
+ : fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
350
408
  #endif
351
409
 
352
410
  #ifdef FMT_USE_INT128
@@ -371,28 +429,89 @@ template <typename T> auto convert_for_visit(T) -> monostate { return {}; }
371
429
 
372
430
  // Casts a nonnegative integer to unsigned.
373
431
  template <typename Int>
374
- FMT_CONSTEXPR auto to_unsigned(Int value) ->
375
- typename std::make_unsigned<Int>::type {
432
+ FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {
376
433
  FMT_ASSERT(std::is_unsigned<Int>::value || value >= 0, "negative value");
377
- return static_cast<typename std::make_unsigned<Int>::type>(value);
434
+ return static_cast<make_unsigned_t<Int>>(value);
378
435
  }
379
436
 
380
- FMT_CONSTEXPR inline auto is_utf8() -> bool {
381
- FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char section[] = "\u00A7";
382
-
383
- // Avoid buggy sign extensions in MSVC's constant evaluation mode (#2297).
437
+ // A heuristic to detect std::string and std::[experimental::]string_view.
438
+ // It is mainly used to avoid dependency on <[experimental/]string_view>.
439
+ template <typename T, typename Enable = void>
440
+ struct is_std_string_like : std::false_type {};
441
+ template <typename T>
442
+ struct is_std_string_like<T, void_t<decltype(std::declval<T>().find_first_of(
443
+ typename T::value_type(), 0))>>
444
+ : std::is_convertible<decltype(std::declval<T>().data()),
445
+ const typename T::value_type*> {};
446
+
447
+ // Returns true iff the literal encoding is UTF-8.
448
+ constexpr auto is_utf8_enabled() -> bool {
449
+ // Avoid an MSVC sign extension bug: https://github.com/fmtlib/fmt/pull/2297.
384
450
  using uchar = unsigned char;
385
- return FMT_UNICODE || (sizeof(section) == 3 && uchar(section[0]) == 0xC2 &&
386
- uchar(section[1]) == 0xA7);
451
+ return sizeof("\u00A7") == 3 && uchar("\u00A7"[0]) == 0xC2 &&
452
+ uchar("\u00A7"[1]) == 0xA7;
453
+ }
454
+ constexpr auto use_utf8() -> bool {
455
+ return !FMT_MSC_VERSION || is_utf8_enabled();
456
+ }
457
+
458
+ static_assert(!FMT_UNICODE || use_utf8(),
459
+ "Unicode support requires compiling with /utf-8");
460
+
461
+ template <typename Char> FMT_CONSTEXPR auto length(const Char* s) -> size_t {
462
+ size_t len = 0;
463
+ while (*s++) ++len;
464
+ return len;
465
+ }
466
+
467
+ template <typename Char>
468
+ FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, std::size_t n)
469
+ -> int {
470
+ if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);
471
+ for (; n != 0; ++s1, ++s2, --n) {
472
+ if (*s1 < *s2) return -1;
473
+ if (*s1 > *s2) return 1;
474
+ }
475
+ return 0;
476
+ }
477
+
478
+ namespace adl {
479
+ using namespace std;
480
+
481
+ template <typename Container>
482
+ auto invoke_back_inserter()
483
+ -> decltype(back_inserter(std::declval<Container&>()));
484
+ } // namespace adl
485
+
486
+ template <typename It, typename Enable = std::true_type>
487
+ struct is_back_insert_iterator : std::false_type {};
488
+
489
+ template <typename It>
490
+ struct is_back_insert_iterator<
491
+ It, bool_constant<std::is_same<
492
+ decltype(adl::invoke_back_inserter<typename It::container_type>()),
493
+ It>::value>> : std::true_type {};
494
+
495
+ // Extracts a reference to the container from *insert_iterator.
496
+ template <typename OutputIt>
497
+ inline auto get_container(OutputIt it) -> typename OutputIt::container_type& {
498
+ struct accessor : OutputIt {
499
+ accessor(OutputIt base) : OutputIt(base) {}
500
+ using OutputIt::container;
501
+ };
502
+ return *accessor(it).container;
387
503
  }
388
504
  } // namespace detail
389
505
 
506
+ // Checks whether T is a container with contiguous storage.
507
+ template <typename T> struct is_contiguous : std::false_type {};
508
+
390
509
  /**
391
- An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
392
- subset of the API. ``fmt::basic_string_view`` is used for format strings even
393
- if ``std::string_view`` is available to prevent issues when a library is
394
- compiled with a different ``-std`` option than the client code (which is not
395
- recommended).
510
+ * An implementation of `std::basic_string_view` for pre-C++17. It provides a
511
+ * subset of the API. `fmt::basic_string_view` is used for format strings even
512
+ * if `std::basic_string_view` is available to prevent issues when a library is
513
+ * compiled with a different `-std` option than the client code (which is not
514
+ * recommended).
396
515
  */
397
516
  FMT_EXPORT
398
517
  template <typename Char> class basic_string_view {
@@ -406,40 +525,33 @@ template <typename Char> class basic_string_view {
406
525
 
407
526
  constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
408
527
 
409
- /** Constructs a string reference object from a C string and a size. */
528
+ /// Constructs a string reference object from a C string and a size.
410
529
  constexpr basic_string_view(const Char* s, size_t count) noexcept
411
530
  : data_(s), size_(count) {}
412
531
 
413
- /**
414
- \rst
415
- Constructs a string reference object from a C string computing
416
- the size with ``std::char_traits<Char>::length``.
417
- \endrst
418
- */
419
- FMT_CONSTEXPR_CHAR_TRAITS
420
- FMT_INLINE
532
+ constexpr basic_string_view(std::nullptr_t) = delete;
533
+
534
+ /// Constructs a string reference object from a C string.
535
+ FMT_CONSTEXPR20
421
536
  basic_string_view(const Char* s)
422
537
  : data_(s),
423
538
  size_(detail::const_check(std::is_same<Char, char>::value &&
424
- !detail::is_constant_evaluated(true))
425
- ? std::strlen(reinterpret_cast<const char*>(s))
426
- : std::char_traits<Char>::length(s)) {}
427
-
428
- /** Constructs a string reference from a ``std::basic_string`` object. */
429
- template <typename Traits, typename Alloc>
430
- FMT_CONSTEXPR basic_string_view(
431
- const std::basic_string<Char, Traits, Alloc>& s) noexcept
432
- : data_(s.data()), size_(s.size()) {}
539
+ !detail::is_constant_evaluated(false))
540
+ ? strlen(reinterpret_cast<const char*>(s))
541
+ : detail::length(s)) {}
433
542
 
434
- template <typename S, FMT_ENABLE_IF(std::is_same<
435
- S, detail::std_string_view<Char>>::value)>
436
- FMT_CONSTEXPR basic_string_view(S s) noexcept
543
+ /// Constructs a string reference from a `std::basic_string` or a
544
+ /// `std::basic_string_view` object.
545
+ template <typename S,
546
+ FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<
547
+ typename S::value_type, Char>::value)>
548
+ FMT_CONSTEXPR basic_string_view(const S& s) noexcept
437
549
  : data_(s.data()), size_(s.size()) {}
438
550
 
439
- /** Returns a pointer to the string data. */
551
+ /// Returns a pointer to the string data.
440
552
  constexpr auto data() const noexcept -> const Char* { return data_; }
441
553
 
442
- /** Returns the string size. */
554
+ /// Returns the string size.
443
555
  constexpr auto size() const noexcept -> size_t { return size_; }
444
556
 
445
557
  constexpr auto begin() const noexcept -> iterator { return data_; }
@@ -454,30 +566,28 @@ template <typename Char> class basic_string_view {
454
566
  size_ -= n;
455
567
  }
456
568
 
457
- FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(
458
- basic_string_view<Char> sv) const noexcept {
459
- return size_ >= sv.size_ &&
460
- std::char_traits<Char>::compare(data_, sv.data_, sv.size_) == 0;
569
+ FMT_CONSTEXPR auto starts_with(basic_string_view<Char> sv) const noexcept
570
+ -> bool {
571
+ return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0;
461
572
  }
462
- FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(Char c) const noexcept {
463
- return size_ >= 1 && std::char_traits<Char>::eq(*data_, c);
573
+ FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool {
574
+ return size_ >= 1 && *data_ == c;
464
575
  }
465
- FMT_CONSTEXPR_CHAR_TRAITS bool starts_with(const Char* s) const {
576
+ FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool {
466
577
  return starts_with(basic_string_view<Char>(s));
467
578
  }
468
579
 
469
580
  // Lexicographically compare this string reference to other.
470
- FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int {
581
+ FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
471
582
  size_t str_size = size_ < other.size_ ? size_ : other.size_;
472
- int result = std::char_traits<Char>::compare(data_, other.data_, str_size);
583
+ int result = detail::compare(data_, other.data_, str_size);
473
584
  if (result == 0)
474
585
  result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
475
586
  return result;
476
587
  }
477
588
 
478
- FMT_CONSTEXPR_CHAR_TRAITS friend auto operator==(basic_string_view lhs,
479
- basic_string_view rhs)
480
- -> bool {
589
+ FMT_CONSTEXPR friend auto operator==(basic_string_view lhs,
590
+ basic_string_view rhs) -> bool {
481
591
  return lhs.compare(rhs) == 0;
482
592
  }
483
593
  friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
@@ -500,26 +610,23 @@ template <typename Char> class basic_string_view {
500
610
  FMT_EXPORT
501
611
  using string_view = basic_string_view<char>;
502
612
 
503
- /** Specifies if ``T`` is a character type. Can be specialized by users. */
613
+ /// Specifies if `T` is a character type. Can be specialized by users.
504
614
  FMT_EXPORT
505
615
  template <typename T> struct is_char : std::false_type {};
506
616
  template <> struct is_char<char> : std::true_type {};
507
617
 
508
618
  namespace detail {
509
619
 
510
- // A base class for compile-time strings.
511
- struct compile_string {};
512
-
513
- template <typename S>
514
- struct is_compile_string : std::is_base_of<compile_string, S> {};
515
-
620
+ // Constructs fmt::basic_string_view<Char> from types implicitly convertible
621
+ // to it, deducing Char. Explicitly convertible types such as the ones returned
622
+ // from FMT_STRING are intentionally excluded.
516
623
  template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
517
- FMT_INLINE auto to_string_view(const Char* s) -> basic_string_view<Char> {
624
+ constexpr auto to_string_view(const Char* s) -> basic_string_view<Char> {
518
625
  return s;
519
626
  }
520
- template <typename Char, typename Traits, typename Alloc>
521
- inline auto to_string_view(const std::basic_string<Char, Traits, Alloc>& s)
522
- -> basic_string_view<Char> {
627
+ template <typename T, FMT_ENABLE_IF(is_std_string_like<T>::value)>
628
+ constexpr auto to_string_view(const T& s)
629
+ -> basic_string_view<typename T::value_type> {
523
630
  return s;
524
631
  }
525
632
  template <typename Char>
@@ -527,31 +634,25 @@ constexpr auto to_string_view(basic_string_view<Char> s)
527
634
  -> basic_string_view<Char> {
528
635
  return s;
529
636
  }
530
- template <typename Char,
531
- FMT_ENABLE_IF(!std::is_empty<std_string_view<Char>>::value)>
532
- inline auto to_string_view(std_string_view<Char> s) -> basic_string_view<Char> {
533
- return s;
534
- }
535
- template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
536
- constexpr auto to_string_view(const S& s)
537
- -> basic_string_view<typename S::char_type> {
538
- return basic_string_view<typename S::char_type>(s);
539
- }
540
- void to_string_view(...);
541
637
 
542
- // Specifies whether S is a string type convertible to fmt::basic_string_view.
543
- // It should be a constexpr function but MSVC 2017 fails to compile it in
544
- // enable_if and MSVC 2015 fails to compile it as an alias template.
545
- // ADL is intentionally disabled as to_string_view is not an extension point.
546
- template <typename S>
547
- struct is_string
548
- : std::is_class<decltype(detail::to_string_view(std::declval<S>()))> {};
638
+ template <typename T, typename Enable = void>
639
+ struct has_to_string_view : std::false_type {};
640
+ // detail:: is intentional since to_string_view is not an extension point.
641
+ template <typename T>
642
+ struct has_to_string_view<
643
+ T, void_t<decltype(detail::to_string_view(std::declval<T>()))>>
644
+ : std::true_type {};
549
645
 
550
- template <typename S, typename = void> struct char_t_impl {};
551
- template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> {
552
- using result = decltype(to_string_view(std::declval<S>()));
553
- using type = typename result::value_type;
646
+ template <typename Char, Char... C> struct string_literal {
647
+ static constexpr Char value[sizeof...(C)] = {C...};
648
+ constexpr operator basic_string_view<Char>() const {
649
+ return {value, sizeof...(C)};
650
+ }
554
651
  };
652
+ #if FMT_CPLUSPLUS < 201703L
653
+ template <typename Char, Char... C>
654
+ constexpr Char string_literal<Char, C...>::value[sizeof...(C)];
655
+ #endif
555
656
 
556
657
  enum class type {
557
658
  none_type,
@@ -600,10 +701,10 @@ FMT_TYPE_CONSTANT(const Char*, cstring_type);
600
701
  FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);
601
702
  FMT_TYPE_CONSTANT(const void*, pointer_type);
602
703
 
603
- constexpr bool is_integral_type(type t) {
704
+ constexpr auto is_integral_type(type t) -> bool {
604
705
  return t > type::none_type && t <= type::last_integer_type;
605
706
  }
606
- constexpr bool is_arithmetic_type(type t) {
707
+ constexpr auto is_arithmetic_type(type t) -> bool {
607
708
  return t > type::none_type && t <= type::last_numeric_type;
608
709
  }
609
710
 
@@ -626,31 +727,27 @@ enum {
626
727
  cstring_set = set(type::cstring_type),
627
728
  pointer_set = set(type::pointer_type)
628
729
  };
629
-
630
- FMT_NORETURN FMT_API void throw_format_error(const char* message);
631
-
632
- struct error_handler {
633
- constexpr error_handler() = default;
634
-
635
- // This function is intentionally not constexpr to give a compile-time error.
636
- FMT_NORETURN void on_error(const char* message) {
637
- throw_format_error(message);
638
- }
639
- };
640
730
  } // namespace detail
641
731
 
642
- /** Throws ``format_error`` with a given message. */
643
- using detail::throw_format_error;
732
+ /// Reports a format error at compile time or, via a `format_error` exception,
733
+ /// at runtime.
734
+ // This function is intentionally not constexpr to give a compile-time error.
735
+ FMT_NORETURN FMT_API void report_error(const char* message);
644
736
 
645
- /** String's character type. */
646
- template <typename S> using char_t = typename detail::char_t_impl<S>::type;
737
+ FMT_DEPRECATED FMT_NORETURN inline void throw_format_error(
738
+ const char* message) {
739
+ report_error(message);
740
+ }
741
+
742
+ /// String's character (code unit) type.
743
+ template <typename S,
744
+ typename V = decltype(detail::to_string_view(std::declval<S>()))>
745
+ using char_t = typename V::value_type;
647
746
 
648
747
  /**
649
- \rst
650
- Parsing context consisting of a format string range being parsed and an
651
- argument counter for automatic indexing.
652
- You can use the ``format_parse_context`` type alias for ``char`` instead.
653
- \endrst
748
+ * Parsing context consisting of a format string range being parsed and an
749
+ * argument counter for automatic indexing.
750
+ * You can use the `format_parse_context` type alias for `char` instead.
654
751
  */
655
752
  FMT_EXPORT
656
753
  template <typename Char> class basic_format_parse_context {
@@ -668,32 +765,25 @@ template <typename Char> class basic_format_parse_context {
668
765
  basic_string_view<Char> format_str, int next_arg_id = 0)
669
766
  : format_str_(format_str), next_arg_id_(next_arg_id) {}
670
767
 
671
- /**
672
- Returns an iterator to the beginning of the format string range being
673
- parsed.
674
- */
768
+ /// Returns an iterator to the beginning of the format string range being
769
+ /// parsed.
675
770
  constexpr auto begin() const noexcept -> iterator {
676
771
  return format_str_.begin();
677
772
  }
678
773
 
679
- /**
680
- Returns an iterator past the end of the format string range being parsed.
681
- */
774
+ /// Returns an iterator past the end of the format string range being parsed.
682
775
  constexpr auto end() const noexcept -> iterator { return format_str_.end(); }
683
776
 
684
- /** Advances the begin iterator to ``it``. */
777
+ /// Advances the begin iterator to `it`.
685
778
  FMT_CONSTEXPR void advance_to(iterator it) {
686
779
  format_str_.remove_prefix(detail::to_unsigned(it - begin()));
687
780
  }
688
781
 
689
- /**
690
- Reports an error if using the manual argument indexing; otherwise returns
691
- the next argument index and switches to the automatic indexing.
692
- */
782
+ /// Reports an error if using the manual argument indexing; otherwise returns
783
+ /// the next argument index and switches to the automatic indexing.
693
784
  FMT_CONSTEXPR auto next_arg_id() -> int {
694
785
  if (next_arg_id_ < 0) {
695
- detail::throw_format_error(
696
- "cannot switch from manual to automatic argument indexing");
786
+ report_error("cannot switch from manual to automatic argument indexing");
697
787
  return 0;
698
788
  }
699
789
  int id = next_arg_id_++;
@@ -701,20 +791,19 @@ template <typename Char> class basic_format_parse_context {
701
791
  return id;
702
792
  }
703
793
 
704
- /**
705
- Reports an error if using the automatic argument indexing; otherwise
706
- switches to the manual indexing.
707
- */
794
+ /// Reports an error if using the automatic argument indexing; otherwise
795
+ /// switches to the manual indexing.
708
796
  FMT_CONSTEXPR void check_arg_id(int id) {
709
797
  if (next_arg_id_ > 0) {
710
- detail::throw_format_error(
711
- "cannot switch from automatic to manual argument indexing");
798
+ report_error("cannot switch from automatic to manual argument indexing");
712
799
  return;
713
800
  }
714
801
  next_arg_id_ = -1;
715
802
  do_check_arg_id(id);
716
803
  }
717
- FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {}
804
+ FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {
805
+ next_arg_id_ = -1;
806
+ }
718
807
  FMT_CONSTEXPR void check_dynamic_spec(int arg_id);
719
808
  };
720
809
 
@@ -741,86 +830,53 @@ class compile_parse_context : public basic_format_parse_context<Char> {
741
830
 
742
831
  FMT_CONSTEXPR auto next_arg_id() -> int {
743
832
  int id = base::next_arg_id();
744
- if (id >= num_args_) throw_format_error("argument not found");
833
+ if (id >= num_args_) report_error("argument not found");
745
834
  return id;
746
835
  }
747
836
 
748
837
  FMT_CONSTEXPR void check_arg_id(int id) {
749
838
  base::check_arg_id(id);
750
- if (id >= num_args_) throw_format_error("argument not found");
839
+ if (id >= num_args_) report_error("argument not found");
751
840
  }
752
841
  using base::check_arg_id;
753
842
 
754
843
  FMT_CONSTEXPR void check_dynamic_spec(int arg_id) {
755
844
  detail::ignore_unused(arg_id);
756
- #if !defined(__LCC__)
757
845
  if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id]))
758
- throw_format_error("width/precision is not integer");
759
- #endif
846
+ report_error("width/precision is not integer");
760
847
  }
761
848
  };
762
849
 
763
- // Extracts a reference to the container from back_insert_iterator.
764
- template <typename Container>
765
- inline auto get_container(std::back_insert_iterator<Container> it)
766
- -> Container& {
767
- using base = std::back_insert_iterator<Container>;
768
- struct accessor : base {
769
- accessor(base b) : base(b) {}
770
- using base::container;
771
- };
772
- return *accessor(it).container;
773
- }
774
-
775
- template <typename Char, typename InputIt, typename OutputIt>
776
- FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out)
777
- -> OutputIt {
778
- while (begin != end) *out++ = static_cast<Char>(*begin++);
779
- return out;
780
- }
781
-
782
- template <typename Char, typename T, typename U,
783
- FMT_ENABLE_IF(
784
- std::is_same<remove_const_t<T>, U>::value&& is_char<U>::value)>
785
- FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* {
786
- if (is_constant_evaluated()) return copy_str<Char, T*, U*>(begin, end, out);
787
- auto size = to_unsigned(end - begin);
788
- if (size > 0) memcpy(out, begin, size * sizeof(U));
789
- return out + size;
790
- }
791
-
792
- /**
793
- \rst
794
- A contiguous memory buffer with an optional growing ability. It is an internal
795
- class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`.
796
- \endrst
797
- */
850
+ /// A contiguous memory buffer with an optional growing ability. It is an
851
+ /// internal class and shouldn't be used directly, only via `memory_buffer`.
798
852
  template <typename T> class buffer {
799
853
  private:
800
854
  T* ptr_;
801
855
  size_t size_;
802
856
  size_t capacity_;
803
857
 
858
+ using grow_fun = void (*)(buffer& buf, size_t capacity);
859
+ grow_fun grow_;
860
+
804
861
  protected:
805
862
  // Don't initialize ptr_ since it is not accessed to save a few cycles.
806
863
  FMT_MSC_WARNING(suppress : 26495)
807
- buffer(size_t sz) noexcept : size_(sz), capacity_(sz) {}
864
+ FMT_CONSTEXPR20 buffer(grow_fun grow, size_t sz) noexcept
865
+ : size_(sz), capacity_(sz), grow_(grow) {}
808
866
 
809
- FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) noexcept
810
- : ptr_(p), size_(sz), capacity_(cap) {}
867
+ constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,
868
+ size_t cap = 0) noexcept
869
+ : ptr_(p), size_(sz), capacity_(cap), grow_(grow) {}
811
870
 
812
871
  FMT_CONSTEXPR20 ~buffer() = default;
813
872
  buffer(buffer&&) = default;
814
873
 
815
- /** Sets the buffer data and capacity. */
874
+ /// Sets the buffer data and capacity.
816
875
  FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept {
817
876
  ptr_ = buf_data;
818
877
  capacity_ = buf_capacity;
819
878
  }
820
879
 
821
- /** Increases the buffer capacity to hold at least *capacity* elements. */
822
- virtual FMT_CONSTEXPR20 void grow(size_t capacity) = 0;
823
-
824
880
  public:
825
881
  using value_type = T;
826
882
  using const_reference = const T&;
@@ -828,47 +884,59 @@ template <typename T> class buffer {
828
884
  buffer(const buffer&) = delete;
829
885
  void operator=(const buffer&) = delete;
830
886
 
831
- FMT_INLINE auto begin() noexcept -> T* { return ptr_; }
832
- FMT_INLINE auto end() noexcept -> T* { return ptr_ + size_; }
887
+ auto begin() noexcept -> T* { return ptr_; }
888
+ auto end() noexcept -> T* { return ptr_ + size_; }
833
889
 
834
- FMT_INLINE auto begin() const noexcept -> const T* { return ptr_; }
835
- FMT_INLINE auto end() const noexcept -> const T* { return ptr_ + size_; }
890
+ auto begin() const noexcept -> const T* { return ptr_; }
891
+ auto end() const noexcept -> const T* { return ptr_ + size_; }
836
892
 
837
- /** Returns the size of this buffer. */
893
+ /// Returns the size of this buffer.
838
894
  constexpr auto size() const noexcept -> size_t { return size_; }
839
895
 
840
- /** Returns the capacity of this buffer. */
896
+ /// Returns the capacity of this buffer.
841
897
  constexpr auto capacity() const noexcept -> size_t { return capacity_; }
842
898
 
843
- /** Returns a pointer to the buffer data (not null-terminated). */
899
+ /// Returns a pointer to the buffer data (not null-terminated).
844
900
  FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; }
845
901
  FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; }
846
902
 
847
- /** Clears this buffer. */
903
+ /// Clears this buffer.
848
904
  void clear() { size_ = 0; }
849
905
 
850
- // Tries resizing the buffer to contain *count* elements. If T is a POD type
906
+ // Tries resizing the buffer to contain `count` elements. If T is a POD type
851
907
  // the new elements may not be initialized.
852
- FMT_CONSTEXPR20 void try_resize(size_t count) {
908
+ FMT_CONSTEXPR void try_resize(size_t count) {
853
909
  try_reserve(count);
854
910
  size_ = count <= capacity_ ? count : capacity_;
855
911
  }
856
912
 
857
- // Tries increasing the buffer capacity to *new_capacity*. It can increase the
913
+ // Tries increasing the buffer capacity to `new_capacity`. It can increase the
858
914
  // capacity by a smaller amount than requested but guarantees there is space
859
915
  // for at least one additional element either by increasing the capacity or by
860
916
  // flushing the buffer if it is full.
861
- FMT_CONSTEXPR20 void try_reserve(size_t new_capacity) {
862
- if (new_capacity > capacity_) grow(new_capacity);
917
+ FMT_CONSTEXPR void try_reserve(size_t new_capacity) {
918
+ if (new_capacity > capacity_) grow_(*this, new_capacity);
863
919
  }
864
920
 
865
- FMT_CONSTEXPR20 void push_back(const T& value) {
921
+ FMT_CONSTEXPR void push_back(const T& value) {
866
922
  try_reserve(size_ + 1);
867
923
  ptr_[size_++] = value;
868
924
  }
869
925
 
870
- /** Appends data to the end of the buffer. */
871
- template <typename U> void append(const U* begin, const U* end);
926
+ /// Appends data to the end of the buffer.
927
+ template <typename U> void append(const U* begin, const U* end) {
928
+ while (begin != end) {
929
+ auto count = to_unsigned(end - begin);
930
+ try_reserve(size_ + count);
931
+ auto free_cap = capacity_ - size_;
932
+ if (free_cap < count) count = free_cap;
933
+ // A loop is faster than memcpy on small sizes.
934
+ T* out = ptr_ + size_;
935
+ for (size_t i = 0; i < count; ++i) out[i] = begin[i];
936
+ size_ += count;
937
+ begin += count;
938
+ }
939
+ }
872
940
 
873
941
  template <typename Idx> FMT_CONSTEXPR auto operator[](Idx index) -> T& {
874
942
  return ptr_[index];
@@ -902,29 +970,36 @@ class fixed_buffer_traits {
902
970
 
903
971
  // A buffer that writes to an output iterator when flushed.
904
972
  template <typename OutputIt, typename T, typename Traits = buffer_traits>
905
- class iterator_buffer final : public Traits, public buffer<T> {
973
+ class iterator_buffer : public Traits, public buffer<T> {
906
974
  private:
907
975
  OutputIt out_;
908
976
  enum { buffer_size = 256 };
909
977
  T data_[buffer_size];
910
978
 
911
- protected:
912
- FMT_CONSTEXPR20 void grow(size_t) override {
913
- if (this->size() == buffer_size) flush();
979
+ static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
980
+ if (buf.size() == buffer_size) static_cast<iterator_buffer&>(buf).flush();
914
981
  }
915
982
 
916
983
  void flush() {
917
984
  auto size = this->size();
918
985
  this->clear();
919
- out_ = copy_str<T>(data_, data_ + this->limit(size), out_);
986
+ const T* begin = data_;
987
+ const T* end = begin + this->limit(size);
988
+ while (begin != end) *out_++ = *begin++;
920
989
  }
921
990
 
922
991
  public:
923
992
  explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
924
- : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
925
- iterator_buffer(iterator_buffer&& other)
926
- : Traits(other), buffer<T>(data_, 0, buffer_size), out_(other.out_) {}
927
- ~iterator_buffer() { flush(); }
993
+ : Traits(n), buffer<T>(grow, data_, 0, buffer_size), out_(out) {}
994
+ iterator_buffer(iterator_buffer&& other) noexcept
995
+ : Traits(other),
996
+ buffer<T>(grow, data_, 0, buffer_size),
997
+ out_(other.out_) {}
998
+ ~iterator_buffer() {
999
+ // Don't crash if flush fails during unwinding.
1000
+ FMT_TRY { flush(); }
1001
+ FMT_CATCH(...) {}
1002
+ }
928
1003
 
929
1004
  auto out() -> OutputIt {
930
1005
  flush();
@@ -934,17 +1009,16 @@ class iterator_buffer final : public Traits, public buffer<T> {
934
1009
  };
935
1010
 
936
1011
  template <typename T>
937
- class iterator_buffer<T*, T, fixed_buffer_traits> final
938
- : public fixed_buffer_traits,
939
- public buffer<T> {
1012
+ class iterator_buffer<T*, T, fixed_buffer_traits> : public fixed_buffer_traits,
1013
+ public buffer<T> {
940
1014
  private:
941
1015
  T* out_;
942
1016
  enum { buffer_size = 256 };
943
1017
  T data_[buffer_size];
944
1018
 
945
- protected:
946
- FMT_CONSTEXPR20 void grow(size_t) override {
947
- if (this->size() == this->capacity()) flush();
1019
+ static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
1020
+ if (buf.size() == buf.capacity())
1021
+ static_cast<iterator_buffer&>(buf).flush();
948
1022
  }
949
1023
 
950
1024
  void flush() {
@@ -958,10 +1032,10 @@ class iterator_buffer<T*, T, fixed_buffer_traits> final
958
1032
 
959
1033
  public:
960
1034
  explicit iterator_buffer(T* out, size_t n = buffer_size)
961
- : fixed_buffer_traits(n), buffer<T>(out, 0, n), out_(out) {}
962
- iterator_buffer(iterator_buffer&& other)
1035
+ : fixed_buffer_traits(n), buffer<T>(grow, out, 0, n), out_(out) {}
1036
+ iterator_buffer(iterator_buffer&& other) noexcept
963
1037
  : fixed_buffer_traits(other),
964
- buffer<T>(std::move(other)),
1038
+ buffer<T>(static_cast<iterator_buffer&&>(other)),
965
1039
  out_(other.out_) {
966
1040
  if (this->data() != out_) {
967
1041
  this->set(data_, buffer_size);
@@ -979,58 +1053,57 @@ class iterator_buffer<T*, T, fixed_buffer_traits> final
979
1053
  }
980
1054
  };
981
1055
 
982
- template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
983
- protected:
984
- FMT_CONSTEXPR20 void grow(size_t) override {}
985
-
1056
+ template <typename T> class iterator_buffer<T*, T> : public buffer<T> {
986
1057
  public:
987
- explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, ~size_t()) {}
1058
+ explicit iterator_buffer(T* out, size_t = 0)
1059
+ : buffer<T>([](buffer<T>&, size_t) {}, out, 0, ~size_t()) {}
988
1060
 
989
1061
  auto out() -> T* { return &*this->end(); }
990
1062
  };
991
1063
 
992
1064
  // A buffer that writes to a container with the contiguous storage.
993
- template <typename Container>
994
- class iterator_buffer<std::back_insert_iterator<Container>,
995
- enable_if_t<is_contiguous<Container>::value,
996
- typename Container::value_type>>
997
- final : public buffer<typename Container::value_type> {
1065
+ template <typename OutputIt>
1066
+ class iterator_buffer<
1067
+ OutputIt,
1068
+ enable_if_t<detail::is_back_insert_iterator<OutputIt>::value &&
1069
+ is_contiguous<typename OutputIt::container_type>::value,
1070
+ typename OutputIt::container_type::value_type>>
1071
+ : public buffer<typename OutputIt::container_type::value_type> {
998
1072
  private:
999
- Container& container_;
1073
+ using container_type = typename OutputIt::container_type;
1074
+ using value_type = typename container_type::value_type;
1075
+ container_type& container_;
1000
1076
 
1001
- protected:
1002
- FMT_CONSTEXPR20 void grow(size_t capacity) override {
1003
- container_.resize(capacity);
1004
- this->set(&container_[0], capacity);
1077
+ static FMT_CONSTEXPR void grow(buffer<value_type>& buf, size_t capacity) {
1078
+ auto& self = static_cast<iterator_buffer&>(buf);
1079
+ self.container_.resize(capacity);
1080
+ self.set(&self.container_[0], capacity);
1005
1081
  }
1006
1082
 
1007
1083
  public:
1008
- explicit iterator_buffer(Container& c)
1009
- : buffer<typename Container::value_type>(c.size()), container_(c) {}
1010
- explicit iterator_buffer(std::back_insert_iterator<Container> out, size_t = 0)
1084
+ explicit iterator_buffer(container_type& c)
1085
+ : buffer<value_type>(grow, c.size()), container_(c) {}
1086
+ explicit iterator_buffer(OutputIt out, size_t = 0)
1011
1087
  : iterator_buffer(get_container(out)) {}
1012
1088
 
1013
- auto out() -> std::back_insert_iterator<Container> {
1014
- return std::back_inserter(container_);
1015
- }
1089
+ auto out() -> OutputIt { return back_inserter(container_); }
1016
1090
  };
1017
1091
 
1018
1092
  // A buffer that counts the number of code units written discarding the output.
1019
- template <typename T = char> class counting_buffer final : public buffer<T> {
1093
+ template <typename T = char> class counting_buffer : public buffer<T> {
1020
1094
  private:
1021
1095
  enum { buffer_size = 256 };
1022
1096
  T data_[buffer_size];
1023
1097
  size_t count_ = 0;
1024
1098
 
1025
- protected:
1026
- FMT_CONSTEXPR20 void grow(size_t) override {
1027
- if (this->size() != buffer_size) return;
1028
- count_ += this->size();
1029
- this->clear();
1099
+ static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
1100
+ if (buf.size() != buffer_size) return;
1101
+ static_cast<counting_buffer&>(buf).count_ += buf.size();
1102
+ buf.clear();
1030
1103
  }
1031
1104
 
1032
1105
  public:
1033
- counting_buffer() : buffer<T>(data_, 0, buffer_size) {}
1106
+ counting_buffer() : buffer<T>(grow, data_, 0, buffer_size) {}
1034
1107
 
1035
1108
  auto count() -> size_t { return count_ + this->size(); }
1036
1109
  };
@@ -1044,7 +1117,7 @@ FMT_CONSTEXPR void basic_format_parse_context<Char>::do_check_arg_id(int id) {
1044
1117
  (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200)) {
1045
1118
  using context = detail::compile_parse_context<Char>;
1046
1119
  if (id >= static_cast<context*>(this)->num_args())
1047
- detail::throw_format_error("argument not found");
1120
+ report_error("argument not found");
1048
1121
  }
1049
1122
  }
1050
1123
 
@@ -1076,21 +1149,75 @@ template <typename T, typename Context>
1076
1149
  using has_formatter =
1077
1150
  std::is_constructible<typename Context::template formatter_type<T>>;
1078
1151
 
1079
- // An output iterator that appends to a buffer.
1080
- // It is used to reduce symbol sizes for the common case.
1081
- class appender : public std::back_insert_iterator<detail::buffer<char>> {
1082
- using base = std::back_insert_iterator<detail::buffer<char>>;
1152
+ // An output iterator that appends to a buffer. It is used instead of
1153
+ // back_insert_iterator to reduce symbol sizes and avoid <iterator> dependency.
1154
+ template <typename T> class basic_appender {
1155
+ private:
1156
+ detail::buffer<T>* buffer_;
1157
+
1158
+ friend auto get_container(basic_appender app) -> detail::buffer<T>& {
1159
+ return *app.buffer_;
1160
+ }
1083
1161
 
1084
1162
  public:
1085
- using std::back_insert_iterator<detail::buffer<char>>::back_insert_iterator;
1086
- appender(base it) noexcept : base(it) {}
1087
- FMT_UNCHECKED_ITERATOR(appender);
1163
+ using iterator_category = int;
1164
+ using value_type = T;
1165
+ using difference_type = ptrdiff_t;
1166
+ using pointer = T*;
1167
+ using reference = T&;
1168
+ using container_type = detail::buffer<T>;
1169
+ FMT_UNCHECKED_ITERATOR(basic_appender);
1088
1170
 
1089
- auto operator++() noexcept -> appender& { return *this; }
1090
- auto operator++(int) noexcept -> appender { return *this; }
1171
+ FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : buffer_(&buf) {}
1172
+
1173
+ auto operator=(T c) -> basic_appender& {
1174
+ buffer_->push_back(c);
1175
+ return *this;
1176
+ }
1177
+ auto operator*() -> basic_appender& { return *this; }
1178
+ auto operator++() -> basic_appender& { return *this; }
1179
+ auto operator++(int) -> basic_appender { return *this; }
1091
1180
  };
1092
1181
 
1182
+ using appender = basic_appender<char>;
1183
+
1093
1184
  namespace detail {
1185
+ template <typename T>
1186
+ struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
1187
+
1188
+ template <typename T, typename Enable = void>
1189
+ struct locking : std::true_type {};
1190
+ template <typename T>
1191
+ struct locking<T, void_t<typename formatter<remove_cvref_t<T>>::nonlocking>>
1192
+ : std::false_type {};
1193
+
1194
+ template <typename T = int> FMT_CONSTEXPR inline auto is_locking() -> bool {
1195
+ return locking<T>::value;
1196
+ }
1197
+ template <typename T1, typename T2, typename... Tail>
1198
+ FMT_CONSTEXPR inline auto is_locking() -> bool {
1199
+ return locking<T1>::value || is_locking<T2, Tail...>();
1200
+ }
1201
+
1202
+ // An optimized version of std::copy with the output value type (T).
1203
+ template <typename T, typename InputIt, typename OutputIt,
1204
+ FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
1205
+ auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
1206
+ get_container(out).append(begin, end);
1207
+ return out;
1208
+ }
1209
+
1210
+ template <typename T, typename InputIt, typename OutputIt,
1211
+ FMT_ENABLE_IF(!is_back_insert_iterator<OutputIt>::value)>
1212
+ FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
1213
+ while (begin != end) *out++ = static_cast<T>(*begin++);
1214
+ return out;
1215
+ }
1216
+
1217
+ template <typename T, typename V, typename OutputIt>
1218
+ FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
1219
+ return copy<T>(s.begin(), s.end(), out);
1220
+ }
1094
1221
 
1095
1222
  template <typename Context, typename T>
1096
1223
  constexpr auto has_const_formatter_impl(T*)
@@ -1108,23 +1235,30 @@ constexpr auto has_const_formatter() -> bool {
1108
1235
  return has_const_formatter_impl<Context>(static_cast<T*>(nullptr));
1109
1236
  }
1110
1237
 
1111
- template <typename T>
1112
- using buffer_appender = conditional_t<std::is_same<T, char>::value, appender,
1113
- std::back_insert_iterator<buffer<T>>>;
1238
+ template <typename It, typename Enable = std::true_type>
1239
+ struct is_buffer_appender : std::false_type {};
1240
+ template <typename It>
1241
+ struct is_buffer_appender<
1242
+ It, bool_constant<
1243
+ is_back_insert_iterator<It>::value &&
1244
+ std::is_base_of<buffer<typename It::container_type::value_type>,
1245
+ typename It::container_type>::value>>
1246
+ : std::true_type {};
1114
1247
 
1115
1248
  // Maps an output iterator to a buffer.
1116
- template <typename T, typename OutputIt>
1249
+ template <typename T, typename OutputIt,
1250
+ FMT_ENABLE_IF(!is_buffer_appender<OutputIt>::value)>
1117
1251
  auto get_buffer(OutputIt out) -> iterator_buffer<OutputIt, T> {
1118
1252
  return iterator_buffer<OutputIt, T>(out);
1119
1253
  }
1120
- template <typename T, typename Buf,
1121
- FMT_ENABLE_IF(std::is_base_of<buffer<char>, Buf>::value)>
1122
- auto get_buffer(std::back_insert_iterator<Buf> out) -> buffer<char>& {
1254
+ template <typename T, typename OutputIt,
1255
+ FMT_ENABLE_IF(is_buffer_appender<OutputIt>::value)>
1256
+ auto get_buffer(OutputIt out) -> buffer<T>& {
1123
1257
  return get_container(out);
1124
1258
  }
1125
1259
 
1126
1260
  template <typename Buf, typename OutputIt>
1127
- FMT_INLINE auto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) {
1261
+ auto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) {
1128
1262
  return buf.out();
1129
1263
  }
1130
1264
  template <typename T, typename OutputIt>
@@ -1145,61 +1279,12 @@ template <typename Char> struct named_arg_info {
1145
1279
  int id;
1146
1280
  };
1147
1281
 
1148
- template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
1149
- struct arg_data {
1150
- // args_[0].named_args points to named_args_ to avoid bloating format_args.
1151
- // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1152
- T args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
1153
- named_arg_info<Char> named_args_[NUM_NAMED_ARGS];
1154
-
1155
- template <typename... U>
1156
- arg_data(const U&... init) : args_{T(named_args_, NUM_NAMED_ARGS), init...} {}
1157
- arg_data(const arg_data& other) = delete;
1158
- auto args() const -> const T* { return args_ + 1; }
1159
- auto named_args() -> named_arg_info<Char>* { return named_args_; }
1160
- };
1161
-
1162
- template <typename T, typename Char, size_t NUM_ARGS>
1163
- struct arg_data<T, Char, NUM_ARGS, 0> {
1164
- // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1165
- T args_[NUM_ARGS != 0 ? NUM_ARGS : +1];
1166
-
1167
- template <typename... U>
1168
- FMT_CONSTEXPR FMT_INLINE arg_data(const U&... init) : args_{init...} {}
1169
- FMT_CONSTEXPR FMT_INLINE auto args() const -> const T* { return args_; }
1170
- FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t {
1171
- return nullptr;
1172
- }
1173
- };
1174
-
1175
- template <typename Char>
1176
- inline void init_named_args(named_arg_info<Char>*, int, int) {}
1177
-
1178
1282
  template <typename T> struct is_named_arg : std::false_type {};
1179
1283
  template <typename T> struct is_statically_named_arg : std::false_type {};
1180
1284
 
1181
1285
  template <typename T, typename Char>
1182
1286
  struct is_named_arg<named_arg<Char, T>> : std::true_type {};
1183
1287
 
1184
- template <typename Char, typename T, typename... Tail,
1185
- FMT_ENABLE_IF(!is_named_arg<T>::value)>
1186
- void init_named_args(named_arg_info<Char>* named_args, int arg_count,
1187
- int named_arg_count, const T&, const Tail&... args) {
1188
- init_named_args(named_args, arg_count + 1, named_arg_count, args...);
1189
- }
1190
-
1191
- template <typename Char, typename T, typename... Tail,
1192
- FMT_ENABLE_IF(is_named_arg<T>::value)>
1193
- void init_named_args(named_arg_info<Char>* named_args, int arg_count,
1194
- int named_arg_count, const T& arg, const Tail&... args) {
1195
- named_args[named_arg_count++] = {arg.name, arg_count};
1196
- init_named_args(named_args, arg_count + 1, named_arg_count, args...);
1197
- }
1198
-
1199
- template <typename... Args>
1200
- FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int,
1201
- const Args&...) {}
1202
-
1203
1288
  template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
1204
1289
  template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
1205
1290
  return (B1 ? 1 : 0) + count<B2, Tail...>();
@@ -1258,33 +1343,40 @@ template <typename Context> class value {
1258
1343
  named_arg_value<char_type> named_args;
1259
1344
  };
1260
1345
 
1261
- constexpr FMT_INLINE value() : no_value() {}
1262
- constexpr FMT_INLINE value(int val) : int_value(val) {}
1263
- constexpr FMT_INLINE value(unsigned val) : uint_value(val) {}
1264
- constexpr FMT_INLINE value(long long val) : long_long_value(val) {}
1265
- constexpr FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {}
1266
- FMT_INLINE value(int128_opt val) : int128_value(val) {}
1267
- FMT_INLINE value(uint128_opt val) : uint128_value(val) {}
1268
- constexpr FMT_INLINE value(float val) : float_value(val) {}
1269
- constexpr FMT_INLINE value(double val) : double_value(val) {}
1270
- FMT_INLINE value(long double val) : long_double_value(val) {}
1271
- constexpr FMT_INLINE value(bool val) : bool_value(val) {}
1272
- constexpr FMT_INLINE value(char_type val) : char_value(val) {}
1273
- FMT_CONSTEXPR FMT_INLINE value(const char_type* val) {
1346
+ constexpr FMT_ALWAYS_INLINE value() : no_value() {}
1347
+ constexpr FMT_ALWAYS_INLINE value(int val) : int_value(val) {}
1348
+ constexpr FMT_ALWAYS_INLINE value(unsigned val) : uint_value(val) {}
1349
+ constexpr FMT_ALWAYS_INLINE value(long long val) : long_long_value(val) {}
1350
+ constexpr FMT_ALWAYS_INLINE value(unsigned long long val)
1351
+ : ulong_long_value(val) {}
1352
+ FMT_ALWAYS_INLINE value(int128_opt val) : int128_value(val) {}
1353
+ FMT_ALWAYS_INLINE value(uint128_opt val) : uint128_value(val) {}
1354
+ constexpr FMT_ALWAYS_INLINE value(float val) : float_value(val) {}
1355
+ constexpr FMT_ALWAYS_INLINE value(double val) : double_value(val) {}
1356
+ FMT_ALWAYS_INLINE value(long double val) : long_double_value(val) {}
1357
+ constexpr FMT_ALWAYS_INLINE value(bool val) : bool_value(val) {}
1358
+ constexpr FMT_ALWAYS_INLINE value(char_type val) : char_value(val) {}
1359
+ FMT_CONSTEXPR FMT_ALWAYS_INLINE value(const char_type* val) {
1274
1360
  string.data = val;
1275
1361
  if (is_constant_evaluated()) string.size = {};
1276
1362
  }
1277
- FMT_CONSTEXPR FMT_INLINE value(basic_string_view<char_type> val) {
1363
+ FMT_CONSTEXPR FMT_ALWAYS_INLINE value(basic_string_view<char_type> val) {
1278
1364
  string.data = val.data();
1279
1365
  string.size = val.size();
1280
1366
  }
1281
- FMT_INLINE value(const void* val) : pointer(val) {}
1282
- FMT_INLINE value(const named_arg_info<char_type>* args, size_t size)
1367
+ FMT_ALWAYS_INLINE value(const void* val) : pointer(val) {}
1368
+ FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)
1283
1369
  : named_args{args, size} {}
1284
1370
 
1285
- template <typename T> FMT_CONSTEXPR20 FMT_INLINE value(T& val) {
1371
+ template <typename T> FMT_CONSTEXPR20 FMT_ALWAYS_INLINE value(T& val) {
1286
1372
  using value_type = remove_const_t<T>;
1287
- custom.value = const_cast<value_type*>(std::addressof(val));
1373
+ // T may overload operator& e.g. std::vector<bool>::reference in libc++.
1374
+ #if defined(__cpp_if_constexpr)
1375
+ if constexpr (std::is_same<decltype(&val), T*>::value)
1376
+ custom.value = const_cast<value_type*>(&val);
1377
+ #endif
1378
+ if (!is_constant_evaluated())
1379
+ custom.value = const_cast<char*>(&reinterpret_cast<const char&>(val));
1288
1380
  // Get the formatter type through the context to allow different contexts
1289
1381
  // have different extension points, e.g. `formatter<T>` for `format` and
1290
1382
  // `printf_formatter<T>` for `printf`.
@@ -1305,7 +1397,9 @@ template <typename Context> class value {
1305
1397
  parse_ctx.advance_to(f.parse(parse_ctx));
1306
1398
  using qualified_type =
1307
1399
  conditional_t<has_const_formatter<T, Context>(), const T, T>;
1308
- ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx));
1400
+ // format must be const for compatibility with std::format and compilation.
1401
+ const auto& cf = f;
1402
+ ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));
1309
1403
  }
1310
1404
  };
1311
1405
 
@@ -1318,7 +1412,7 @@ using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
1318
1412
  template <typename T> struct format_as_result {
1319
1413
  template <typename U,
1320
1414
  FMT_ENABLE_IF(std::is_enum<U>::value || std::is_class<U>::value)>
1321
- static auto map(U*) -> decltype(format_as(std::declval<U>()));
1415
+ static auto map(U*) -> remove_cvref_t<decltype(format_as(std::declval<U>()))>;
1322
1416
  static auto map(...) -> void;
1323
1417
 
1324
1418
  using type = decltype(map(static_cast<T*>(nullptr)));
@@ -1329,42 +1423,33 @@ template <typename T>
1329
1423
  struct has_format_as
1330
1424
  : bool_constant<!std::is_same<format_as_t<T>, void>::value> {};
1331
1425
 
1426
+ #define FMT_MAP_API FMT_CONSTEXPR FMT_ALWAYS_INLINE
1427
+
1332
1428
  // Maps formatting arguments to core types.
1333
1429
  // arg_mapper reports errors by returning unformattable instead of using
1334
1430
  // static_assert because it's used in the is_formattable trait.
1335
1431
  template <typename Context> struct arg_mapper {
1336
1432
  using char_type = typename Context::char_type;
1337
1433
 
1338
- FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int { return val; }
1339
- FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned {
1434
+ FMT_MAP_API auto map(signed char val) -> int { return val; }
1435
+ FMT_MAP_API auto map(unsigned char val) -> unsigned { return val; }
1436
+ FMT_MAP_API auto map(short val) -> int { return val; }
1437
+ FMT_MAP_API auto map(unsigned short val) -> unsigned { return val; }
1438
+ FMT_MAP_API auto map(int val) -> int { return val; }
1439
+ FMT_MAP_API auto map(unsigned val) -> unsigned { return val; }
1440
+ FMT_MAP_API auto map(long val) -> long_type { return val; }
1441
+ FMT_MAP_API auto map(unsigned long val) -> ulong_type { return val; }
1442
+ FMT_MAP_API auto map(long long val) -> long long { return val; }
1443
+ FMT_MAP_API auto map(unsigned long long val) -> unsigned long long {
1340
1444
  return val;
1341
1445
  }
1342
- FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int { return val; }
1343
- FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned {
1344
- return val;
1345
- }
1346
- FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int { return val; }
1347
- FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned { return val; }
1348
- FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type { return val; }
1349
- FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type {
1350
- return val;
1351
- }
1352
- FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long { return val; }
1353
- FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val)
1354
- -> unsigned long long {
1355
- return val;
1356
- }
1357
- FMT_CONSTEXPR FMT_INLINE auto map(int128_opt val) -> int128_opt {
1358
- return val;
1359
- }
1360
- FMT_CONSTEXPR FMT_INLINE auto map(uint128_opt val) -> uint128_opt {
1361
- return val;
1362
- }
1363
- FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool { return val; }
1446
+ FMT_MAP_API auto map(int128_opt val) -> int128_opt { return val; }
1447
+ FMT_MAP_API auto map(uint128_opt val) -> uint128_opt { return val; }
1448
+ FMT_MAP_API auto map(bool val) -> bool { return val; }
1364
1449
 
1365
1450
  template <typename T, FMT_ENABLE_IF(std::is_same<T, char>::value ||
1366
1451
  std::is_same<T, char_type>::value)>
1367
- FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type {
1452
+ FMT_MAP_API auto map(T val) -> char_type {
1368
1453
  return val;
1369
1454
  }
1370
1455
  template <typename T, enable_if_t<(std::is_same<T, wchar_t>::value ||
@@ -1375,43 +1460,38 @@ template <typename Context> struct arg_mapper {
1375
1460
  std::is_same<T, char32_t>::value) &&
1376
1461
  !std::is_same<T, char_type>::value,
1377
1462
  int> = 0>
1378
- FMT_CONSTEXPR FMT_INLINE auto map(T) -> unformattable_char {
1463
+ FMT_MAP_API auto map(T) -> unformattable_char {
1379
1464
  return {};
1380
1465
  }
1381
1466
 
1382
- FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; }
1383
- FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; }
1384
- FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double {
1385
- return val;
1386
- }
1467
+ FMT_MAP_API auto map(float val) -> float { return val; }
1468
+ FMT_MAP_API auto map(double val) -> double { return val; }
1469
+ FMT_MAP_API auto map(long double val) -> long double { return val; }
1387
1470
 
1388
- FMT_CONSTEXPR FMT_INLINE auto map(char_type* val) -> const char_type* {
1389
- return val;
1390
- }
1391
- FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* {
1392
- return val;
1393
- }
1394
- template <typename T,
1395
- FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value &&
1396
- std::is_same<char_type, char_t<T>>::value)>
1397
- FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
1398
- -> basic_string_view<char_type> {
1471
+ FMT_MAP_API auto map(char_type* val) -> const char_type* { return val; }
1472
+ FMT_MAP_API auto map(const char_type* val) -> const char_type* { return val; }
1473
+ template <typename T, typename Char = char_t<T>,
1474
+ FMT_ENABLE_IF(std::is_same<Char, char_type>::value &&
1475
+ !std::is_pointer<T>::value)>
1476
+ FMT_MAP_API auto map(const T& val) -> basic_string_view<Char> {
1399
1477
  return to_string_view(val);
1400
1478
  }
1401
- template <typename T,
1402
- FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value &&
1403
- !std::is_same<char_type, char_t<T>>::value)>
1404
- FMT_CONSTEXPR FMT_INLINE auto map(const T&) -> unformattable_char {
1479
+ template <typename T, typename Char = char_t<T>,
1480
+ FMT_ENABLE_IF(!std::is_same<Char, char_type>::value &&
1481
+ !std::is_pointer<T>::value)>
1482
+ FMT_MAP_API auto map(const T&) -> unformattable_char {
1405
1483
  return {};
1406
1484
  }
1407
1485
 
1408
- FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; }
1409
- FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* {
1410
- return val;
1486
+ FMT_MAP_API auto map(void* val) -> const void* { return val; }
1487
+ FMT_MAP_API auto map(const void* val) -> const void* { return val; }
1488
+ FMT_MAP_API auto map(volatile void* val) -> const void* {
1489
+ return const_cast<const void*>(val);
1411
1490
  }
1412
- FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* {
1413
- return val;
1491
+ FMT_MAP_API auto map(const volatile void* val) -> const void* {
1492
+ return const_cast<const void*>(val);
1414
1493
  }
1494
+ FMT_MAP_API auto map(std::nullptr_t val) -> const void* { return val; }
1415
1495
 
1416
1496
  // Use SFINAE instead of a const T* parameter to avoid a conflict with the
1417
1497
  // array overload.
@@ -1420,23 +1500,22 @@ template <typename Context> struct arg_mapper {
1420
1500
  FMT_ENABLE_IF(
1421
1501
  std::is_pointer<T>::value || std::is_member_pointer<T>::value ||
1422
1502
  std::is_function<typename std::remove_pointer<T>::type>::value ||
1423
- (std::is_convertible<const T&, const void*>::value &&
1424
- !std::is_convertible<const T&, const char_type*>::value &&
1425
- !has_formatter<T, Context>::value))>
1503
+ (std::is_array<T>::value &&
1504
+ !std::is_convertible<T, const char_type*>::value))>
1426
1505
  FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer {
1427
1506
  return {};
1428
1507
  }
1429
1508
 
1430
1509
  template <typename T, std::size_t N,
1431
1510
  FMT_ENABLE_IF(!std::is_same<T, wchar_t>::value)>
1432
- FMT_CONSTEXPR FMT_INLINE auto map(const T (&values)[N]) -> const T (&)[N] {
1511
+ FMT_MAP_API auto map(const T (&values)[N]) -> const T (&)[N] {
1433
1512
  return values;
1434
1513
  }
1435
1514
 
1436
1515
  // Only map owning types because mapping views can be unsafe.
1437
1516
  template <typename T, typename U = format_as_t<T>,
1438
1517
  FMT_ENABLE_IF(std::is_arithmetic<U>::value)>
1439
- FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> decltype(this->map(U())) {
1518
+ FMT_MAP_API auto map(const T& val) -> decltype(FMT_DECLTYPE_THIS map(U())) {
1440
1519
  return map(format_as(val));
1441
1520
  }
1442
1521
 
@@ -1446,27 +1525,29 @@ template <typename Context> struct arg_mapper {
1446
1525
  !std::is_const<T>::value)> {};
1447
1526
 
1448
1527
  template <typename T, FMT_ENABLE_IF(formattable<T>::value)>
1449
- FMT_CONSTEXPR FMT_INLINE auto do_map(T& val) -> T& {
1528
+ FMT_MAP_API auto do_map(T& val) -> T& {
1450
1529
  return val;
1451
1530
  }
1452
1531
  template <typename T, FMT_ENABLE_IF(!formattable<T>::value)>
1453
- FMT_CONSTEXPR FMT_INLINE auto do_map(T&) -> unformattable {
1532
+ FMT_MAP_API auto do_map(T&) -> unformattable {
1454
1533
  return {};
1455
1534
  }
1456
1535
 
1536
+ // is_fundamental is used to allow formatters for extended FP types.
1457
1537
  template <typename T, typename U = remove_const_t<T>,
1458
- FMT_ENABLE_IF((std::is_class<U>::value || std::is_enum<U>::value ||
1459
- std::is_union<U>::value) &&
1460
- !is_string<U>::value && !is_char<U>::value &&
1461
- !is_named_arg<U>::value &&
1462
- !std::is_arithmetic<format_as_t<U>>::value)>
1463
- FMT_CONSTEXPR FMT_INLINE auto map(T& val) -> decltype(this->do_map(val)) {
1538
+ FMT_ENABLE_IF(
1539
+ (std::is_class<U>::value || std::is_enum<U>::value ||
1540
+ std::is_union<U>::value || std::is_fundamental<U>::value) &&
1541
+ !has_to_string_view<U>::value && !is_char<U>::value &&
1542
+ !is_named_arg<U>::value && !std::is_integral<U>::value &&
1543
+ !std::is_arithmetic<format_as_t<U>>::value)>
1544
+ FMT_MAP_API auto map(T& val) -> decltype(FMT_DECLTYPE_THIS do_map(val)) {
1464
1545
  return do_map(val);
1465
1546
  }
1466
1547
 
1467
1548
  template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
1468
- FMT_CONSTEXPR FMT_INLINE auto map(const T& named_arg)
1469
- -> decltype(this->map(named_arg.value)) {
1549
+ FMT_MAP_API auto map(const T& named_arg)
1550
+ -> decltype(FMT_DECLTYPE_THIS map(named_arg.value)) {
1470
1551
  return map(named_arg.value);
1471
1552
  }
1472
1553
 
@@ -1485,45 +1566,14 @@ enum { max_packed_args = 62 / packed_arg_bits };
1485
1566
  enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
1486
1567
  enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
1487
1568
 
1488
- template <typename Char, typename InputIt>
1489
- auto copy_str(InputIt begin, InputIt end, appender out) -> appender {
1490
- get_container(out).append(begin, end);
1491
- return out;
1492
- }
1493
- template <typename Char, typename InputIt>
1494
- auto copy_str(InputIt begin, InputIt end,
1495
- std::back_insert_iterator<std::string> out)
1496
- -> std::back_insert_iterator<std::string> {
1497
- get_container(out).append(begin, end);
1498
- return out;
1499
- }
1500
-
1501
- template <typename Char, typename R, typename OutputIt>
1502
- FMT_CONSTEXPR auto copy_str(R&& rng, OutputIt out) -> OutputIt {
1503
- return detail::copy_str<Char>(rng.begin(), rng.end(), out);
1504
- }
1505
-
1506
- #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
1507
- // A workaround for gcc 4.8 to make void_t work in a SFINAE context.
1508
- template <typename...> struct void_t_impl { using type = void; };
1509
- template <typename... T> using void_t = typename void_t_impl<T...>::type;
1510
- #else
1511
- template <typename...> using void_t = void;
1512
- #endif
1513
-
1514
1569
  template <typename It, typename T, typename Enable = void>
1515
1570
  struct is_output_iterator : std::false_type {};
1516
1571
 
1572
+ template <> struct is_output_iterator<appender, char> : std::true_type {};
1573
+
1517
1574
  template <typename It, typename T>
1518
1575
  struct is_output_iterator<
1519
- It, T,
1520
- void_t<typename std::iterator_traits<It>::iterator_category,
1521
- decltype(*std::declval<It>() = std::declval<T>())>>
1522
- : std::true_type {};
1523
-
1524
- template <typename It> struct is_back_insert_iterator : std::false_type {};
1525
- template <typename Container>
1526
- struct is_back_insert_iterator<std::back_insert_iterator<Container>>
1576
+ It, T, void_t<decltype(*std::declval<It&>()++ = std::declval<T>())>>
1527
1577
  : std::true_type {};
1528
1578
 
1529
1579
  // A type-erased reference to an std::locale to avoid a heavy <locale> include.
@@ -1532,7 +1582,7 @@ class locale_ref {
1532
1582
  const void* locale_; // A type-erased pointer to std::locale.
1533
1583
 
1534
1584
  public:
1535
- constexpr FMT_INLINE locale_ref() : locale_(nullptr) {}
1585
+ constexpr locale_ref() : locale_(nullptr) {}
1536
1586
  template <typename Locale> explicit locale_ref(const Locale& loc);
1537
1587
 
1538
1588
  explicit operator bool() const noexcept { return locale_ != nullptr; }
@@ -1550,32 +1600,45 @@ constexpr auto encode_types() -> unsigned long long {
1550
1600
  (encode_types<Context, Args...>() << packed_arg_bits);
1551
1601
  }
1552
1602
 
1553
- #if defined(__cpp_if_constexpr)
1554
- // This type is intentionally undefined, only used for errors
1555
- template <typename T, typename Char> struct type_is_unformattable_for;
1603
+ template <typename Context, typename... T, size_t NUM_ARGS = sizeof...(T)>
1604
+ constexpr unsigned long long make_descriptor() {
1605
+ return NUM_ARGS <= max_packed_args ? encode_types<Context, T...>()
1606
+ : is_unpacked_bit | NUM_ARGS;
1607
+ }
1608
+
1609
+ // This type is intentionally undefined, only used for errors.
1610
+ template <typename T, typename Char>
1611
+ #if FMT_CLANG_VERSION && FMT_CLANG_VERSION <= 1500
1612
+ // https://github.com/fmtlib/fmt/issues/3796
1613
+ struct type_is_unformattable_for {
1614
+ };
1615
+ #else
1616
+ struct type_is_unformattable_for;
1556
1617
  #endif
1557
1618
 
1558
1619
  template <bool PACKED, typename Context, typename T, FMT_ENABLE_IF(PACKED)>
1559
- FMT_CONSTEXPR FMT_INLINE auto make_arg(T& val) -> value<Context> {
1620
+ FMT_CONSTEXPR auto make_arg(T& val) -> value<Context> {
1560
1621
  using arg_type = remove_cvref_t<decltype(arg_mapper<Context>().map(val))>;
1561
1622
 
1562
- constexpr bool formattable_char =
1563
- !std::is_same<arg_type, unformattable_char>::value;
1623
+ // Use enum instead of constexpr because the latter may generate code.
1624
+ enum {
1625
+ formattable_char = !std::is_same<arg_type, unformattable_char>::value
1626
+ };
1564
1627
  static_assert(formattable_char, "Mixing character types is disallowed.");
1565
1628
 
1566
1629
  // Formatting of arbitrary pointers is disallowed. If you want to format a
1567
1630
  // pointer cast it to `void*` or `const void*`. In particular, this forbids
1568
1631
  // formatting of `[const] volatile char*` printed as bool by iostreams.
1569
- constexpr bool formattable_pointer =
1570
- !std::is_same<arg_type, unformattable_pointer>::value;
1632
+ enum {
1633
+ formattable_pointer = !std::is_same<arg_type, unformattable_pointer>::value
1634
+ };
1571
1635
  static_assert(formattable_pointer,
1572
1636
  "Formatting of non-void pointers is disallowed.");
1573
1637
 
1574
- constexpr bool formattable = !std::is_same<arg_type, unformattable>::value;
1638
+ enum { formattable = !std::is_same<arg_type, unformattable>::value };
1575
1639
  #if defined(__cpp_if_constexpr)
1576
- if constexpr (!formattable) {
1640
+ if constexpr (!formattable)
1577
1641
  type_is_unformattable_for<T, typename Context::char_type> _;
1578
- }
1579
1642
  #endif
1580
1643
  static_assert(
1581
1644
  formattable,
@@ -1596,11 +1659,70 @@ template <bool PACKED, typename Context, typename T, FMT_ENABLE_IF(!PACKED)>
1596
1659
  FMT_CONSTEXPR inline auto make_arg(T& val) -> basic_format_arg<Context> {
1597
1660
  return make_arg<Context>(val);
1598
1661
  }
1662
+
1663
+ template <typename Context, size_t NUM_ARGS>
1664
+ using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
1665
+ basic_format_arg<Context>>;
1666
+
1667
+ template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
1668
+ void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
1669
+ ++arg_index;
1670
+ }
1671
+ template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
1672
+ void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
1673
+ int& named_arg_index, const T& arg) {
1674
+ named_args[named_arg_index++] = {arg.name, arg_index++};
1675
+ }
1676
+
1677
+ // An array of references to arguments. It can be implicitly converted to
1678
+ // `fmt::basic_format_args` for passing into type-erased formatting functions
1679
+ // such as `fmt::vformat`.
1680
+ template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
1681
+ unsigned long long DESC>
1682
+ struct format_arg_store {
1683
+ // args_[0].named_args points to named_args to avoid bloating format_args.
1684
+ // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1685
+ static constexpr size_t ARGS_ARR_SIZE = 1 + (NUM_ARGS != 0 ? NUM_ARGS : +1);
1686
+
1687
+ arg_t<Context, NUM_ARGS> args[ARGS_ARR_SIZE];
1688
+ named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];
1689
+
1690
+ template <typename... T>
1691
+ FMT_MAP_API format_arg_store(T&... values)
1692
+ : args{{named_args, NUM_NAMED_ARGS},
1693
+ make_arg<NUM_ARGS <= max_packed_args, Context>(values)...} {
1694
+ using dummy = int[];
1695
+ int arg_index = 0, named_arg_index = 0;
1696
+ (void)dummy{
1697
+ 0,
1698
+ (init_named_arg(named_args, arg_index, named_arg_index, values), 0)...};
1699
+ }
1700
+
1701
+ format_arg_store(format_arg_store&& rhs) {
1702
+ args[0] = {named_args, NUM_NAMED_ARGS};
1703
+ for (size_t i = 1; i < ARGS_ARR_SIZE; ++i) args[i] = rhs.args[i];
1704
+ for (size_t i = 0; i < NUM_NAMED_ARGS; ++i)
1705
+ named_args[i] = rhs.named_args[i];
1706
+ }
1707
+
1708
+ format_arg_store(const format_arg_store& rhs) = delete;
1709
+ format_arg_store& operator=(const format_arg_store& rhs) = delete;
1710
+ format_arg_store& operator=(format_arg_store&& rhs) = delete;
1711
+ };
1712
+
1713
+ // A specialization of format_arg_store without named arguments.
1714
+ // It is a plain struct to reduce binary size in debug mode.
1715
+ template <typename Context, size_t NUM_ARGS, unsigned long long DESC>
1716
+ struct format_arg_store<Context, NUM_ARGS, 0, DESC> {
1717
+ // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
1718
+ arg_t<Context, NUM_ARGS> args[NUM_ARGS != 0 ? NUM_ARGS : +1];
1719
+ };
1720
+
1599
1721
  } // namespace detail
1600
1722
  FMT_BEGIN_EXPORT
1601
1723
 
1602
- // A formatting argument. It is a trivially copyable/constructible type to
1603
- // allow storage in basic_memory_buffer.
1724
+ // A formatting argument. Context is a template parameter for the compiled API
1725
+ // where output can be unbuffered.
1604
1726
  template <typename Context> class basic_format_arg {
1605
1727
  private:
1606
1728
  detail::value<Context> value_;
@@ -1610,18 +1732,13 @@ template <typename Context> class basic_format_arg {
1610
1732
  friend FMT_CONSTEXPR auto detail::make_arg(T& value)
1611
1733
  -> basic_format_arg<ContextType>;
1612
1734
 
1613
- template <typename Visitor, typename Ctx>
1614
- friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis,
1615
- const basic_format_arg<Ctx>& arg)
1616
- -> decltype(vis(0));
1617
-
1618
1735
  friend class basic_format_args<Context>;
1619
1736
  friend class dynamic_format_arg_store<Context>;
1620
1737
 
1621
1738
  using char_type = typename Context::char_type;
1622
1739
 
1623
- template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
1624
- friend struct detail::arg_data;
1740
+ template <typename, size_t, size_t, unsigned long long>
1741
+ friend struct detail::format_arg_store;
1625
1742
 
1626
1743
  basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
1627
1744
  : value_(args, size) {}
@@ -1652,209 +1769,75 @@ template <typename Context> class basic_format_arg {
1652
1769
  auto is_arithmetic() const -> bool {
1653
1770
  return detail::is_arithmetic_type(type_);
1654
1771
  }
1655
- };
1656
-
1657
- /**
1658
- \rst
1659
- Visits an argument dispatching to the appropriate visit method based on
1660
- the argument type. For example, if the argument type is ``double`` then
1661
- ``vis(value)`` will be called with the value of type ``double``.
1662
- \endrst
1663
- */
1664
- // DEPRECATED!
1665
- FMT_EXPORT
1666
- template <typename Visitor, typename Context>
1667
- FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(
1668
- Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
1669
- switch (arg.type_) {
1670
- case detail::type::none_type:
1671
- break;
1672
- case detail::type::int_type:
1673
- return vis(arg.value_.int_value);
1674
- case detail::type::uint_type:
1675
- return vis(arg.value_.uint_value);
1676
- case detail::type::long_long_type:
1677
- return vis(arg.value_.long_long_value);
1678
- case detail::type::ulong_long_type:
1679
- return vis(arg.value_.ulong_long_value);
1680
- case detail::type::int128_type:
1681
- return vis(detail::convert_for_visit(arg.value_.int128_value));
1682
- case detail::type::uint128_type:
1683
- return vis(detail::convert_for_visit(arg.value_.uint128_value));
1684
- case detail::type::bool_type:
1685
- return vis(arg.value_.bool_value);
1686
- case detail::type::char_type:
1687
- return vis(arg.value_.char_value);
1688
- case detail::type::float_type:
1689
- return vis(arg.value_.float_value);
1690
- case detail::type::double_type:
1691
- return vis(arg.value_.double_value);
1692
- case detail::type::long_double_type:
1693
- return vis(arg.value_.long_double_value);
1694
- case detail::type::cstring_type:
1695
- return vis(arg.value_.string.data);
1696
- case detail::type::string_type:
1697
- using sv = basic_string_view<typename Context::char_type>;
1698
- return vis(sv(arg.value_.string.data, arg.value_.string.size));
1699
- case detail::type::pointer_type:
1700
- return vis(arg.value_.pointer);
1701
- case detail::type::custom_type:
1702
- return vis(typename basic_format_arg<Context>::handle(arg.value_.custom));
1703
- }
1704
- return vis(monostate());
1705
- }
1706
-
1707
- // Formatting context.
1708
- template <typename OutputIt, typename Char> class basic_format_context {
1709
- private:
1710
- OutputIt out_;
1711
- basic_format_args<basic_format_context> args_;
1712
- detail::locale_ref loc_;
1713
-
1714
- public:
1715
- using iterator = OutputIt;
1716
- using format_arg = basic_format_arg<basic_format_context>;
1717
- using format_args = basic_format_args<basic_format_context>;
1718
- using parse_context_type = basic_format_parse_context<Char>;
1719
- template <typename T> using formatter_type = formatter<T, Char>;
1720
1772
 
1721
- /** The character type for the output. */
1722
- using char_type = Char;
1723
-
1724
- basic_format_context(basic_format_context&&) = default;
1725
- basic_format_context(const basic_format_context&) = delete;
1726
- void operator=(const basic_format_context&) = delete;
1727
1773
  /**
1728
- Constructs a ``basic_format_context`` object. References to the arguments
1729
- are stored in the object so make sure they have appropriate lifetimes.
1774
+ * Visits an argument dispatching to the appropriate visit method based on
1775
+ * the argument type. For example, if the argument type is `double` then
1776
+ * `vis(value)` will be called with the value of type `double`.
1730
1777
  */
1731
- constexpr basic_format_context(OutputIt out, format_args ctx_args,
1732
- detail::locale_ref loc = {})
1733
- : out_(out), args_(ctx_args), loc_(loc) {}
1734
-
1735
- constexpr auto arg(int id) const -> format_arg { return args_.get(id); }
1736
- FMT_CONSTEXPR auto arg(basic_string_view<Char> name) -> format_arg {
1737
- return args_.get(name);
1738
- }
1739
- FMT_CONSTEXPR auto arg_id(basic_string_view<Char> name) -> int {
1740
- return args_.get_id(name);
1778
+ template <typename Visitor>
1779
+ FMT_CONSTEXPR FMT_INLINE auto visit(Visitor&& vis) const -> decltype(vis(0)) {
1780
+ switch (type_) {
1781
+ case detail::type::none_type:
1782
+ break;
1783
+ case detail::type::int_type:
1784
+ return vis(value_.int_value);
1785
+ case detail::type::uint_type:
1786
+ return vis(value_.uint_value);
1787
+ case detail::type::long_long_type:
1788
+ return vis(value_.long_long_value);
1789
+ case detail::type::ulong_long_type:
1790
+ return vis(value_.ulong_long_value);
1791
+ case detail::type::int128_type:
1792
+ return vis(detail::convert_for_visit(value_.int128_value));
1793
+ case detail::type::uint128_type:
1794
+ return vis(detail::convert_for_visit(value_.uint128_value));
1795
+ case detail::type::bool_type:
1796
+ return vis(value_.bool_value);
1797
+ case detail::type::char_type:
1798
+ return vis(value_.char_value);
1799
+ case detail::type::float_type:
1800
+ return vis(value_.float_value);
1801
+ case detail::type::double_type:
1802
+ return vis(value_.double_value);
1803
+ case detail::type::long_double_type:
1804
+ return vis(value_.long_double_value);
1805
+ case detail::type::cstring_type:
1806
+ return vis(value_.string.data);
1807
+ case detail::type::string_type:
1808
+ using sv = basic_string_view<typename Context::char_type>;
1809
+ return vis(sv(value_.string.data, value_.string.size));
1810
+ case detail::type::pointer_type:
1811
+ return vis(value_.pointer);
1812
+ case detail::type::custom_type:
1813
+ return vis(typename basic_format_arg<Context>::handle(value_.custom));
1814
+ }
1815
+ return vis(monostate());
1741
1816
  }
1742
- auto args() const -> const format_args& { return args_; }
1743
-
1744
- FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; }
1745
- void on_error(const char* message) { error_handler().on_error(message); }
1746
-
1747
- // Returns an iterator to the beginning of the output range.
1748
- FMT_CONSTEXPR auto out() -> iterator { return out_; }
1749
1817
 
1750
- // Advances the begin iterator to ``it``.
1751
- void advance_to(iterator it) {
1752
- if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
1818
+ auto format_custom(const char_type* parse_begin,
1819
+ typename Context::parse_context_type& parse_ctx,
1820
+ Context& ctx) -> bool {
1821
+ if (type_ != detail::type::custom_type) return false;
1822
+ parse_ctx.advance_to(parse_begin);
1823
+ value_.custom.format(value_.custom.value, parse_ctx, ctx);
1824
+ return true;
1753
1825
  }
1754
-
1755
- FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
1756
1826
  };
1757
1827
 
1758
- template <typename Char>
1759
- using buffer_context =
1760
- basic_format_context<detail::buffer_appender<Char>, Char>;
1761
- using format_context = buffer_context<char>;
1762
-
1763
- template <typename T, typename Char = char>
1764
- using is_formattable = bool_constant<!std::is_base_of<
1765
- detail::unformattable, decltype(detail::arg_mapper<buffer_context<Char>>()
1766
- .map(std::declval<T&>()))>::value>;
1767
-
1768
- /**
1769
- \rst
1770
- An array of references to arguments. It can be implicitly converted into
1771
- `~fmt::basic_format_args` for passing into type-erased formatting functions
1772
- such as `~fmt::vformat`.
1773
- \endrst
1774
- */
1775
- template <typename Context, typename... Args>
1776
- class format_arg_store
1777
- #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1778
- // Workaround a GCC template argument substitution bug.
1779
- : public basic_format_args<Context>
1780
- #endif
1781
- {
1782
- private:
1783
- static const size_t num_args = sizeof...(Args);
1784
- static constexpr size_t num_named_args = detail::count_named_args<Args...>();
1785
- static const bool is_packed = num_args <= detail::max_packed_args;
1786
-
1787
- using value_type = conditional_t<is_packed, detail::value<Context>,
1788
- basic_format_arg<Context>>;
1789
-
1790
- detail::arg_data<value_type, typename Context::char_type, num_args,
1791
- num_named_args>
1792
- data_;
1793
-
1794
- friend class basic_format_args<Context>;
1795
-
1796
- static constexpr unsigned long long desc =
1797
- (is_packed ? detail::encode_types<Context, Args...>()
1798
- : detail::is_unpacked_bit | num_args) |
1799
- (num_named_args != 0
1800
- ? static_cast<unsigned long long>(detail::has_named_args_bit)
1801
- : 0);
1802
-
1803
- public:
1804
- template <typename... T>
1805
- FMT_CONSTEXPR FMT_INLINE format_arg_store(T&... args)
1806
- :
1807
- #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1808
- basic_format_args<Context>(*this),
1809
- #endif
1810
- data_{detail::make_arg<is_packed, Context>(args)...} {
1811
- if (detail::const_check(num_named_args != 0))
1812
- detail::init_named_args(data_.named_args(), 0, 0, args...);
1813
- }
1814
- };
1815
-
1816
- /**
1817
- \rst
1818
- Constructs a `~fmt::format_arg_store` object that contains references to
1819
- arguments and can be implicitly converted to `~fmt::format_args`. `Context`
1820
- can be omitted in which case it defaults to `~fmt::format_context`.
1821
- See `~fmt::arg` for lifetime considerations.
1822
- \endrst
1823
- */
1824
- // Arguments are taken by lvalue references to avoid some lifetime issues.
1825
- template <typename Context = format_context, typename... T>
1826
- constexpr auto make_format_args(T&... args)
1827
- -> format_arg_store<Context, remove_cvref_t<T>...> {
1828
- return {args...};
1829
- }
1830
-
1831
- /**
1832
- \rst
1833
- Returns a named argument to be used in a formatting function.
1834
- It should only be used in a call to a formatting function or
1835
- `dynamic_format_arg_store::push_back`.
1836
-
1837
- **Example**::
1838
-
1839
- fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23));
1840
- \endrst
1841
- */
1842
- template <typename Char, typename T>
1843
- inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
1844
- static_assert(!detail::is_named_arg<T>(), "nested named arguments");
1845
- return {name, arg};
1828
+ template <typename Visitor, typename Context>
1829
+ FMT_DEPRECATED FMT_CONSTEXPR auto visit_format_arg(
1830
+ Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
1831
+ return arg.visit(static_cast<Visitor&&>(vis));
1846
1832
  }
1847
- FMT_END_EXPORT
1848
1833
 
1849
1834
  /**
1850
- \rst
1851
- A view of a collection of formatting arguments. To avoid lifetime issues it
1852
- should only be used as a parameter type in type-erased functions such as
1853
- ``vformat``::
1854
-
1855
- void vlog(string_view format_str, format_args args); // OK
1856
- format_args args = make_format_args(); // Error: dangling reference
1857
- \endrst
1835
+ * A view of a collection of formatting arguments. To avoid lifetime issues it
1836
+ * should only be used as a parameter type in type-erased functions such as
1837
+ * `vformat`:
1838
+ *
1839
+ * void vlog(fmt::string_view fmt, fmt::format_args args); // OK
1840
+ * fmt::format_args args = fmt::make_format_args(); // Dangling reference
1858
1841
  */
1859
1842
  template <typename Context> class basic_format_args {
1860
1843
  public:
@@ -1880,7 +1863,7 @@ template <typename Context> class basic_format_args {
1880
1863
  constexpr auto is_packed() const -> bool {
1881
1864
  return (desc_ & detail::is_unpacked_bit) == 0;
1882
1865
  }
1883
- auto has_named_args() const -> bool {
1866
+ constexpr auto has_named_args() const -> bool {
1884
1867
  return (desc_ & detail::has_named_args_bit) != 0;
1885
1868
  }
1886
1869
 
@@ -1890,53 +1873,40 @@ template <typename Context> class basic_format_args {
1890
1873
  return static_cast<detail::type>((desc_ >> shift) & mask);
1891
1874
  }
1892
1875
 
1893
- constexpr FMT_INLINE basic_format_args(unsigned long long desc,
1894
- const detail::value<Context>* values)
1895
- : desc_(desc), values_(values) {}
1896
- constexpr basic_format_args(unsigned long long desc, const format_arg* args)
1897
- : desc_(desc), args_(args) {}
1898
-
1899
1876
  public:
1900
1877
  constexpr basic_format_args() : desc_(0), args_(nullptr) {}
1901
1878
 
1902
- /**
1903
- \rst
1904
- Constructs a `basic_format_args` object from `~fmt::format_arg_store`.
1905
- \endrst
1906
- */
1907
- template <typename... Args>
1908
- constexpr FMT_INLINE basic_format_args(
1909
- const format_arg_store<Context, Args...>& store)
1910
- : basic_format_args(format_arg_store<Context, Args...>::desc,
1911
- store.data_.args()) {}
1912
-
1913
- /**
1914
- \rst
1915
- Constructs a `basic_format_args` object from
1916
- `~fmt::dynamic_format_arg_store`.
1917
- \endrst
1918
- */
1919
- constexpr FMT_INLINE basic_format_args(
1920
- const dynamic_format_arg_store<Context>& store)
1921
- : basic_format_args(store.get_types(), store.data()) {}
1922
-
1923
- /**
1924
- \rst
1925
- Constructs a `basic_format_args` object from a dynamic set of arguments.
1926
- \endrst
1927
- */
1879
+ /// Constructs a `basic_format_args` object from `format_arg_store`.
1880
+ template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
1881
+ FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args)>
1882
+ constexpr FMT_ALWAYS_INLINE basic_format_args(
1883
+ const detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>&
1884
+ store)
1885
+ : desc_(DESC), values_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {}
1886
+
1887
+ template <size_t NUM_ARGS, size_t NUM_NAMED_ARGS, unsigned long long DESC,
1888
+ FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>
1889
+ constexpr basic_format_args(
1890
+ const detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>&
1891
+ store)
1892
+ : desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {}
1893
+
1894
+ /// Constructs a `basic_format_args` object from `dynamic_format_arg_store`.
1895
+ constexpr basic_format_args(const dynamic_format_arg_store<Context>& store)
1896
+ : desc_(store.get_types()), args_(store.data()) {}
1897
+
1898
+ /// Constructs a `basic_format_args` object from a dynamic list of arguments.
1928
1899
  constexpr basic_format_args(const format_arg* args, int count)
1929
- : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count),
1930
- args) {}
1900
+ : desc_(detail::is_unpacked_bit | detail::to_unsigned(count)),
1901
+ args_(args) {}
1931
1902
 
1932
- /** Returns the argument with the specified id. */
1903
+ /// Returns the argument with the specified id.
1933
1904
  FMT_CONSTEXPR auto get(int id) const -> format_arg {
1934
1905
  format_arg arg;
1935
1906
  if (!is_packed()) {
1936
1907
  if (id < max_size()) arg = args_[id];
1937
1908
  return arg;
1938
1909
  }
1939
- // [Windows #12702 - Fix fmt CodeQL issues]
1940
1910
  if (static_cast<unsigned>(id) >= detail::max_packed_args) return arg;
1941
1911
  arg.type_ = type(id);
1942
1912
  if (arg.type_ == detail::type::none_type) return arg;
@@ -1951,7 +1921,7 @@ template <typename Context> class basic_format_args {
1951
1921
  }
1952
1922
 
1953
1923
  template <typename Char>
1954
- auto get_id(basic_string_view<Char> name) const -> int {
1924
+ FMT_CONSTEXPR auto get_id(basic_string_view<Char> name) const -> int {
1955
1925
  if (!has_named_args()) return -1;
1956
1926
  const auto& named_args =
1957
1927
  (is_packed() ? values_[-1] : args_[-1].value_).named_args;
@@ -1968,7 +1938,117 @@ template <typename Context> class basic_format_args {
1968
1938
  }
1969
1939
  };
1970
1940
 
1971
- /** An alias to ``basic_format_args<format_context>``. */
1941
+ // A formatting context.
1942
+ class context {
1943
+ private:
1944
+ appender out_;
1945
+ basic_format_args<context> args_;
1946
+ detail::locale_ref loc_;
1947
+
1948
+ public:
1949
+ /// The character type for the output.
1950
+ using char_type = char;
1951
+
1952
+ using iterator = appender;
1953
+ using format_arg = basic_format_arg<context>;
1954
+ using parse_context_type = basic_format_parse_context<char>;
1955
+ template <typename T> using formatter_type = formatter<T, char>;
1956
+
1957
+ /// Constructs a `basic_format_context` object. References to the arguments
1958
+ /// are stored in the object so make sure they have appropriate lifetimes.
1959
+ FMT_CONSTEXPR context(iterator out, basic_format_args<context> ctx_args,
1960
+ detail::locale_ref loc = {})
1961
+ : out_(out), args_(ctx_args), loc_(loc) {}
1962
+ context(context&&) = default;
1963
+ context(const context&) = delete;
1964
+ void operator=(const context&) = delete;
1965
+
1966
+ FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }
1967
+ auto arg(string_view name) -> format_arg { return args_.get(name); }
1968
+ FMT_CONSTEXPR auto arg_id(string_view name) -> int {
1969
+ return args_.get_id(name);
1970
+ }
1971
+ auto args() const -> const basic_format_args<context>& { return args_; }
1972
+
1973
+ // Returns an iterator to the beginning of the output range.
1974
+ FMT_CONSTEXPR auto out() -> iterator { return out_; }
1975
+
1976
+ // Advances the begin iterator to `it`.
1977
+ void advance_to(iterator) {}
1978
+
1979
+ FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
1980
+ };
1981
+
1982
+ template <typename OutputIt, typename Char> class generic_context;
1983
+
1984
+ // Longer aliases for C++20 compatibility.
1985
+ template <typename OutputIt, typename Char>
1986
+ using basic_format_context =
1987
+ conditional_t<std::is_same<OutputIt, appender>::value, context,
1988
+ generic_context<OutputIt, Char>>;
1989
+ using format_context = context;
1990
+
1991
+ template <typename Char>
1992
+ using buffered_context = basic_format_context<basic_appender<Char>, Char>;
1993
+
1994
+ template <typename T, typename Char = char>
1995
+ using is_formattable = bool_constant<!std::is_base_of<
1996
+ detail::unformattable, decltype(detail::arg_mapper<buffered_context<Char>>()
1997
+ .map(std::declval<T&>()))>::value>;
1998
+
1999
+ #if FMT_USE_CONCEPTS
2000
+ template <typename T, typename Char = char>
2001
+ concept formattable = is_formattable<remove_reference_t<T>, Char>::value;
2002
+ #endif
2003
+
2004
+ /**
2005
+ * Constructs an object that stores references to arguments and can be
2006
+ * implicitly converted to `format_args`. `Context` can be omitted in which case
2007
+ * it defaults to `format_context`. See `arg` for lifetime considerations.
2008
+ */
2009
+ // Take arguments by lvalue references to avoid some lifetime issues, e.g.
2010
+ // auto args = make_format_args(std::string());
2011
+ template <typename Context = format_context, typename... T,
2012
+ size_t NUM_ARGS = sizeof...(T),
2013
+ size_t NUM_NAMED_ARGS = detail::count_named_args<T...>(),
2014
+ unsigned long long DESC = detail::make_descriptor<Context, T...>(),
2015
+ FMT_ENABLE_IF(NUM_NAMED_ARGS == 0)>
2016
+ constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)
2017
+ -> detail::format_arg_store<Context, NUM_ARGS, 0, DESC> {
2018
+ return {{detail::make_arg<NUM_ARGS <= detail::max_packed_args, Context>(
2019
+ args)...}};
2020
+ }
2021
+
2022
+ #ifndef FMT_DOC
2023
+ template <typename Context = format_context, typename... T,
2024
+ size_t NUM_NAMED_ARGS = detail::count_named_args<T...>(),
2025
+ unsigned long long DESC =
2026
+ detail::make_descriptor<Context, T...>() |
2027
+ static_cast<unsigned long long>(detail::has_named_args_bit),
2028
+ FMT_ENABLE_IF(NUM_NAMED_ARGS != 0)>
2029
+ constexpr auto make_format_args(T&... args)
2030
+ -> detail::format_arg_store<Context, sizeof...(T), NUM_NAMED_ARGS, DESC> {
2031
+ return {args...};
2032
+ }
2033
+ #endif
2034
+
2035
+ /**
2036
+ * Returns a named argument to be used in a formatting function.
2037
+ * It should only be used in a call to a formatting function or
2038
+ * `dynamic_format_arg_store::push_back`.
2039
+ *
2040
+ * **Example**:
2041
+ *
2042
+ * fmt::print("The answer is {answer}.", fmt::arg("answer", 42));
2043
+ */
2044
+ template <typename Char, typename T>
2045
+ inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
2046
+ static_assert(!detail::is_named_arg<T>(), "nested named arguments");
2047
+ return {name, arg};
2048
+ }
2049
+ FMT_END_EXPORT
2050
+
2051
+ /// An alias for `basic_format_args<format_context>`.
1972
2052
  // A separate type would result in shorter symbols but break ABI compatibility
1973
2053
  // between clang and gcc on ARM (#1919).
1974
2054
  FMT_EXPORT using format_args = basic_format_args<format_context>;
@@ -1994,63 +2074,91 @@ using sign_t = sign::type;
1994
2074
 
1995
2075
  namespace detail {
1996
2076
 
1997
- // Workaround an array initialization issue in gcc 4.8.
1998
- template <typename Char> struct fill_t {
2077
+ template <typename Char>
2078
+ using unsigned_char = typename conditional_t<std::is_integral<Char>::value,
2079
+ std::make_unsigned<Char>,
2080
+ type_identity<unsigned>>::type;
2081
+
2082
+ // Character (code unit) type is erased to prevent template bloat.
2083
+ struct fill_t {
1999
2084
  private:
2000
2085
  enum { max_size = 4 };
2001
- Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)};
2086
+ char data_[max_size] = {' '};
2002
2087
  unsigned char size_ = 1;
2003
2088
 
2004
2089
  public:
2090
+ template <typename Char>
2005
2091
  FMT_CONSTEXPR void operator=(basic_string_view<Char> s) {
2006
2092
  auto size = s.size();
2007
- FMT_ASSERT(size <= max_size, "invalid fill");
2008
- for (size_t i = 0; i < size; ++i) data_[i] = s[i];
2009
2093
  size_ = static_cast<unsigned char>(size);
2094
+ if (size == 1) {
2095
+ unsigned uchar = static_cast<unsigned_char<Char>>(s[0]);
2096
+ data_[0] = static_cast<char>(uchar);
2097
+ data_[1] = static_cast<char>(uchar >> 8);
2098
+ return;
2099
+ }
2100
+ FMT_ASSERT(size <= max_size, "invalid fill");
2101
+ for (size_t i = 0; i < size; ++i) data_[i] = static_cast<char>(s[i]);
2102
+ }
2103
+
2104
+ FMT_CONSTEXPR void operator=(char c) {
2105
+ data_[0] = c;
2106
+ size_ = 1;
2010
2107
  }
2011
2108
 
2012
2109
  constexpr auto size() const -> size_t { return size_; }
2013
- constexpr auto data() const -> const Char* { return data_; }
2014
2110
 
2015
- FMT_CONSTEXPR auto operator[](size_t index) -> Char& { return data_[index]; }
2016
- FMT_CONSTEXPR auto operator[](size_t index) const -> const Char& {
2017
- return data_[index];
2111
+ template <typename Char> constexpr auto get() const -> Char {
2112
+ using uchar = unsigned char;
2113
+ return static_cast<Char>(static_cast<uchar>(data_[0]) |
2114
+ (static_cast<uchar>(data_[1]) << 8));
2115
+ }
2116
+
2117
+ template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char>::value)>
2118
+ constexpr auto data() const -> const Char* {
2119
+ return data_;
2120
+ }
2121
+ template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
2122
+ constexpr auto data() const -> const Char* {
2123
+ return nullptr;
2018
2124
  }
2019
2125
  };
2020
2126
  } // namespace detail
2021
2127
 
2022
2128
  enum class presentation_type : unsigned char {
2023
- none,
2024
- dec, // 'd'
2025
- oct, // 'o'
2026
- hex_lower, // 'x'
2027
- hex_upper, // 'X'
2028
- bin_lower, // 'b'
2029
- bin_upper, // 'B'
2030
- hexfloat_lower, // 'a'
2031
- hexfloat_upper, // 'A'
2032
- exp_lower, // 'e'
2033
- exp_upper, // 'E'
2034
- fixed_lower, // 'f'
2035
- fixed_upper, // 'F'
2036
- general_lower, // 'g'
2037
- general_upper, // 'G'
2038
- chr, // 'c'
2039
- string, // 's'
2040
- pointer, // 'p'
2041
- debug // '?'
2129
+ // Common specifiers:
2130
+ none = 0,
2131
+ debug = 1, // '?'
2132
+ string = 2, // 's' (string, bool)
2133
+
2134
+ // Integral, bool and character specifiers:
2135
+ dec = 3, // 'd'
2136
+ hex, // 'x' or 'X'
2137
+ oct, // 'o'
2138
+ bin, // 'b' or 'B'
2139
+ chr, // 'c'
2140
+
2141
+ // String and pointer specifiers:
2142
+ pointer = 3, // 'p'
2143
+
2144
+ // Floating-point specifiers:
2145
+ exp = 1, // 'e' or 'E' (1 since there is no FP debug presentation)
2146
+ fixed, // 'f' or 'F'
2147
+ general, // 'g' or 'G'
2148
+ hexfloat // 'a' or 'A'
2042
2149
  };
2043
2150
 
2044
2151
  // Format specifiers for built-in and string types.
2045
- template <typename Char = char> struct format_specs {
2152
+ struct format_specs {
2046
2153
  int width;
2047
2154
  int precision;
2048
2155
  presentation_type type;
2049
2156
  align_t align : 4;
2050
2157
  sign_t sign : 3;
2051
- bool alt : 1; // Alternate form ('#').
2158
+ bool upper : 1; // An uppercase version e.g. 'X' for 'x'.
2159
+ bool alt : 1; // Alternate form ('#').
2052
2160
  bool localized : 1;
2053
- detail::fill_t<Char> fill;
2161
+ detail::fill_t fill;
2054
2162
 
2055
2163
  constexpr format_specs()
2056
2164
  : width(0),
@@ -2058,6 +2166,7 @@ template <typename Char = char> struct format_specs {
2058
2166
  type(presentation_type::none),
2059
2167
  align(align::none),
2060
2168
  sign(sign::none),
2169
+ upper(false),
2061
2170
  alt(false),
2062
2171
  localized(false) {}
2063
2172
  };
@@ -2094,8 +2203,7 @@ template <typename Char> struct arg_ref {
2094
2203
  // Format specifiers with width and precision resolved at formatting rather
2095
2204
  // than parsing time to allow reusing the same parsed specifiers with
2096
2205
  // different sets of arguments (precompilation of format strings).
2097
- template <typename Char = char>
2098
- struct dynamic_format_specs : format_specs<Char> {
2206
+ template <typename Char = char> struct dynamic_format_specs : format_specs {
2099
2207
  arg_ref<Char> width_ref;
2100
2208
  arg_ref<Char> precision_ref;
2101
2209
  };
@@ -2105,10 +2213,6 @@ template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
2105
2213
  constexpr auto to_ascii(Char c) -> char {
2106
2214
  return c <= 0xff ? static_cast<char>(c) : '\0';
2107
2215
  }
2108
- template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)>
2109
- constexpr auto to_ascii(Char c) -> char {
2110
- return c <= 0xff ? static_cast<char>(c) : '\0';
2111
- }
2112
2216
 
2113
2217
  // Returns the number of code units in a code point or 1 on error.
2114
2218
  template <typename Char>
@@ -2130,8 +2234,8 @@ FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {
2130
2234
  template <>
2131
2235
  inline auto find<false, char>(const char* first, const char* last, char value,
2132
2236
  const char*& out) -> bool {
2133
- out = static_cast<const char*>(
2134
- std::memchr(first, value, to_unsigned(last - first)));
2237
+ out =
2238
+ static_cast<const char*>(memchr(first, value, to_unsigned(last - first)));
2135
2239
  return out != nullptr;
2136
2240
  }
2137
2241
 
@@ -2150,11 +2254,11 @@ FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
2150
2254
  } while (p != end && '0' <= *p && *p <= '9');
2151
2255
  auto num_digits = p - begin;
2152
2256
  begin = p;
2153
- if (num_digits <= std::numeric_limits<int>::digits10)
2154
- return static_cast<int>(value);
2257
+ int digits10 = static_cast<int>(sizeof(int) * CHAR_BIT * 3 / 10);
2258
+ if (num_digits <= digits10) return static_cast<int>(value);
2155
2259
  // Check for overflow.
2156
- const unsigned max = to_unsigned((std::numeric_limits<int>::max)());
2157
- return num_digits == std::numeric_limits<int>::digits10 + 1 &&
2260
+ unsigned max = INT_MAX;
2261
+ return num_digits == digits10 + 1 &&
2158
2262
  prev * 10ull + unsigned(p[-1] - '0') <= max
2159
2263
  ? static_cast<int>(value)
2160
2264
  : error_value;
@@ -2182,19 +2286,18 @@ FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
2182
2286
  Char c = *begin;
2183
2287
  if (c >= '0' && c <= '9') {
2184
2288
  int index = 0;
2185
- constexpr int max = (std::numeric_limits<int>::max)();
2186
2289
  if (c != '0')
2187
- index = parse_nonnegative_int(begin, end, max);
2290
+ index = parse_nonnegative_int(begin, end, INT_MAX);
2188
2291
  else
2189
2292
  ++begin;
2190
2293
  if (begin == end || (*begin != '}' && *begin != ':'))
2191
- throw_format_error("invalid format string");
2294
+ report_error("invalid format string");
2192
2295
  else
2193
2296
  handler.on_index(index);
2194
2297
  return begin;
2195
2298
  }
2196
2299
  if (!is_name_start(c)) {
2197
- throw_format_error("invalid format string");
2300
+ report_error("invalid format string");
2198
2301
  return begin;
2199
2302
  }
2200
2303
  auto it = begin;
@@ -2206,8 +2309,8 @@ FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
2206
2309
  }
2207
2310
 
2208
2311
  template <typename Char, typename Handler>
2209
- FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end,
2210
- Handler&& handler) -> const Char* {
2312
+ FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end,
2313
+ Handler&& handler) -> const Char* {
2211
2314
  FMT_ASSERT(begin != end, "");
2212
2315
  Char c = *begin;
2213
2316
  if (c != '}' && c != ':') return do_parse_arg_id(begin, end, handler);
@@ -2247,13 +2350,13 @@ FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
2247
2350
  if (val != -1)
2248
2351
  value = val;
2249
2352
  else
2250
- throw_format_error("number is too big");
2353
+ report_error("number is too big");
2251
2354
  } else if (*begin == '{') {
2252
2355
  ++begin;
2253
2356
  auto handler = dynamic_spec_id_handler<Char>{ctx, ref};
2254
2357
  if (begin != end) begin = parse_arg_id(begin, end, handler);
2255
2358
  if (begin != end && *begin == '}') return ++begin;
2256
- throw_format_error("invalid format string");
2359
+ report_error("invalid format string");
2257
2360
  }
2258
2361
  return begin;
2259
2362
  }
@@ -2265,7 +2368,7 @@ FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
2265
2368
  -> const Char* {
2266
2369
  ++begin;
2267
2370
  if (begin == end || *begin == '}') {
2268
- throw_format_error("invalid precision");
2371
+ report_error("invalid precision");
2269
2372
  return begin;
2270
2373
  }
2271
2374
  return parse_dynamic_spec(begin, end, value, ref, ctx);
@@ -2275,9 +2378,10 @@ enum class state { start, align, sign, hash, zero, width, precision, locale };
2275
2378
 
2276
2379
  // Parses standard format specifiers.
2277
2380
  template <typename Char>
2278
- FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2279
- const Char* begin, const Char* end, dynamic_format_specs<Char>& specs,
2280
- basic_format_parse_context<Char>& ctx, type arg_type) -> const Char* {
2381
+ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
2382
+ dynamic_format_specs<Char>& specs,
2383
+ basic_format_parse_context<Char>& ctx,
2384
+ type arg_type) -> const Char* {
2281
2385
  auto c = '\0';
2282
2386
  if (end - begin > 1) {
2283
2387
  auto next = to_ascii(begin[1]);
@@ -2291,7 +2395,7 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2291
2395
  state current_state = state::start;
2292
2396
  FMT_CONSTEXPR void operator()(state s, bool valid = true) {
2293
2397
  if (current_state >= s || !valid)
2294
- throw_format_error("invalid format specifier");
2398
+ report_error("invalid format specifier");
2295
2399
  current_state = s;
2296
2400
  }
2297
2401
  } enter_state;
@@ -2303,9 +2407,12 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2303
2407
  dynamic_format_specs<Char>& specs;
2304
2408
  type arg_type;
2305
2409
 
2306
- FMT_CONSTEXPR auto operator()(pres type, int set) -> const Char* {
2307
- if (!in(arg_type, set)) throw_format_error("invalid format specifier");
2308
- specs.type = type;
2410
+ FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* {
2411
+ if (!in(arg_type, set)) {
2412
+ if (arg_type == type::none_type) return begin;
2413
+ report_error("invalid format specifier");
2414
+ }
2415
+ specs.type = pres_type;
2309
2416
  return begin + 1;
2310
2417
  }
2311
2418
  } parse_presentation_type{begin, specs, arg_type};
@@ -2322,6 +2429,7 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2322
2429
  case '+':
2323
2430
  case '-':
2324
2431
  case ' ':
2432
+ if (arg_type == type::none_type) return begin;
2325
2433
  enter_state(state::sign, in(arg_type, sint_set | float_set));
2326
2434
  switch (c) {
2327
2435
  case '+':
@@ -2337,18 +2445,21 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2337
2445
  ++begin;
2338
2446
  break;
2339
2447
  case '#':
2448
+ if (arg_type == type::none_type) return begin;
2340
2449
  enter_state(state::hash, is_arithmetic_type(arg_type));
2341
2450
  specs.alt = true;
2342
2451
  ++begin;
2343
2452
  break;
2344
2453
  case '0':
2345
2454
  enter_state(state::zero);
2346
- if (!is_arithmetic_type(arg_type))
2347
- throw_format_error("format specifier requires numeric argument");
2455
+ if (!is_arithmetic_type(arg_type)) {
2456
+ if (arg_type == type::none_type) return begin;
2457
+ report_error("format specifier requires numeric argument");
2458
+ }
2348
2459
  if (specs.align == align::none) {
2349
2460
  // Ignore 0 if align is specified for compatibility with std::format.
2350
2461
  specs.align = align::numeric;
2351
- specs.fill[0] = Char('0');
2462
+ specs.fill = '0';
2352
2463
  }
2353
2464
  ++begin;
2354
2465
  break;
@@ -2366,45 +2477,54 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2366
2477
  begin = parse_dynamic_spec(begin, end, specs.width, specs.width_ref, ctx);
2367
2478
  break;
2368
2479
  case '.':
2480
+ if (arg_type == type::none_type) return begin;
2369
2481
  enter_state(state::precision,
2370
2482
  in(arg_type, float_set | string_set | cstring_set));
2371
2483
  begin = parse_precision(begin, end, specs.precision, specs.precision_ref,
2372
2484
  ctx);
2373
2485
  break;
2374
2486
  case 'L':
2487
+ if (arg_type == type::none_type) return begin;
2375
2488
  enter_state(state::locale, is_arithmetic_type(arg_type));
2376
2489
  specs.localized = true;
2377
2490
  ++begin;
2378
2491
  break;
2379
2492
  case 'd':
2380
2493
  return parse_presentation_type(pres::dec, integral_set);
2494
+ case 'X':
2495
+ specs.upper = true;
2496
+ FMT_FALLTHROUGH;
2497
+ case 'x':
2498
+ return parse_presentation_type(pres::hex, integral_set);
2381
2499
  case 'o':
2382
2500
  return parse_presentation_type(pres::oct, integral_set);
2383
- case 'x':
2384
- return parse_presentation_type(pres::hex_lower, integral_set);
2385
- case 'X':
2386
- return parse_presentation_type(pres::hex_upper, integral_set);
2387
- case 'b':
2388
- return parse_presentation_type(pres::bin_lower, integral_set);
2389
2501
  case 'B':
2390
- return parse_presentation_type(pres::bin_upper, integral_set);
2391
- case 'a':
2392
- return parse_presentation_type(pres::hexfloat_lower, float_set);
2393
- case 'A':
2394
- return parse_presentation_type(pres::hexfloat_upper, float_set);
2395
- case 'e':
2396
- return parse_presentation_type(pres::exp_lower, float_set);
2502
+ specs.upper = true;
2503
+ FMT_FALLTHROUGH;
2504
+ case 'b':
2505
+ return parse_presentation_type(pres::bin, integral_set);
2397
2506
  case 'E':
2398
- return parse_presentation_type(pres::exp_upper, float_set);
2399
- case 'f':
2400
- return parse_presentation_type(pres::fixed_lower, float_set);
2507
+ specs.upper = true;
2508
+ FMT_FALLTHROUGH;
2509
+ case 'e':
2510
+ return parse_presentation_type(pres::exp, float_set);
2401
2511
  case 'F':
2402
- return parse_presentation_type(pres::fixed_upper, float_set);
2403
- case 'g':
2404
- return parse_presentation_type(pres::general_lower, float_set);
2512
+ specs.upper = true;
2513
+ FMT_FALLTHROUGH;
2514
+ case 'f':
2515
+ return parse_presentation_type(pres::fixed, float_set);
2405
2516
  case 'G':
2406
- return parse_presentation_type(pres::general_upper, float_set);
2517
+ specs.upper = true;
2518
+ FMT_FALLTHROUGH;
2519
+ case 'g':
2520
+ return parse_presentation_type(pres::general, float_set);
2521
+ case 'A':
2522
+ specs.upper = true;
2523
+ FMT_FALLTHROUGH;
2524
+ case 'a':
2525
+ return parse_presentation_type(pres::hexfloat, float_set);
2407
2526
  case 'c':
2527
+ if (arg_type == type::bool_type) report_error("invalid format specifier");
2408
2528
  return parse_presentation_type(pres::chr, integral_set);
2409
2529
  case 's':
2410
2530
  return parse_presentation_type(pres::string,
@@ -2421,16 +2541,17 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(
2421
2541
  // Parse fill and alignment.
2422
2542
  auto fill_end = begin + code_point_length(begin);
2423
2543
  if (end - fill_end <= 0) {
2424
- throw_format_error("invalid format specifier");
2544
+ report_error("invalid format specifier");
2425
2545
  return begin;
2426
2546
  }
2427
2547
  if (*begin == '{') {
2428
- throw_format_error("invalid fill character '{'");
2548
+ report_error("invalid fill character '{'");
2429
2549
  return begin;
2430
2550
  }
2431
2551
  auto align = parse_align(to_ascii(*fill_end));
2432
2552
  enter_state(state::align, align != align::none);
2433
- specs.fill = {begin, to_unsigned(fill_end - begin)};
2553
+ specs.fill =
2554
+ basic_string_view<Char>(begin, to_unsigned(fill_end - begin));
2434
2555
  specs.align = align;
2435
2556
  begin = fill_end + 1;
2436
2557
  }
@@ -2478,8 +2599,8 @@ FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end,
2478
2599
  }
2479
2600
 
2480
2601
  template <bool IS_CONSTEXPR, typename Char, typename Handler>
2481
- FMT_CONSTEXPR FMT_INLINE void parse_format_string(
2482
- basic_string_view<Char> format_str, Handler&& handler) {
2602
+ FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> format_str,
2603
+ Handler&& handler) {
2483
2604
  auto begin = format_str.data();
2484
2605
  auto end = begin + format_str.size();
2485
2606
  if (end - begin < 32) {
@@ -2535,17 +2656,18 @@ template <typename T> struct strip_named_arg<T, true> {
2535
2656
  };
2536
2657
 
2537
2658
  template <typename T, typename ParseContext>
2659
+ FMT_VISIBILITY("hidden") // Suppress an ld warning on macOS (#3769).
2538
2660
  FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx)
2539
2661
  -> decltype(ctx.begin()) {
2540
2662
  using char_type = typename ParseContext::char_type;
2541
- using context = buffer_context<char_type>;
2663
+ using context = buffered_context<char_type>;
2542
2664
  using mapped_type = conditional_t<
2543
2665
  mapped_type_constant<T, context>::value != type::custom_type,
2544
2666
  decltype(arg_mapper<context>().map(std::declval<const T&>())),
2545
2667
  typename strip_named_arg<T>::type>;
2546
2668
  #if defined(__cpp_if_constexpr)
2547
- if constexpr (std::is_default_constructible_v<
2548
- formatter<mapped_type, char_type>>) {
2669
+ if constexpr (std::is_default_constructible<
2670
+ formatter<mapped_type, char_type>>::value) {
2549
2671
  return formatter<mapped_type, char_type>().parse(ctx);
2550
2672
  } else {
2551
2673
  type_is_unformattable_for<T, char_type> _;
@@ -2557,15 +2679,14 @@ FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx)
2557
2679
  }
2558
2680
 
2559
2681
  // Checks char specs and returns true iff the presentation type is char-like.
2560
- template <typename Char>
2561
- FMT_CONSTEXPR auto check_char_specs(const format_specs<Char>& specs) -> bool {
2682
+ FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool {
2562
2683
  if (specs.type != presentation_type::none &&
2563
2684
  specs.type != presentation_type::chr &&
2564
2685
  specs.type != presentation_type::debug) {
2565
2686
  return false;
2566
2687
  }
2567
2688
  if (specs.align == align::numeric || specs.sign != sign::none || specs.alt)
2568
- throw_format_error("invalid format specifier for char");
2689
+ report_error("invalid format specifier for char");
2569
2690
  return true;
2570
2691
  }
2571
2692
 
@@ -2609,7 +2730,7 @@ template <typename Char, typename... Args> class format_string_checker {
2609
2730
 
2610
2731
  public:
2611
2732
  explicit FMT_CONSTEXPR format_string_checker(basic_string_view<Char> fmt)
2612
- : types_{mapped_type_constant<Args, buffer_context<Char>>::value...},
2733
+ : types_{mapped_type_constant<Args, buffered_context<Char>>::value...},
2613
2734
  context_(fmt, num_args, types_),
2614
2735
  parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
2615
2736
 
@@ -2642,14 +2763,20 @@ template <typename Char, typename... Args> class format_string_checker {
2642
2763
  return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin;
2643
2764
  }
2644
2765
 
2645
- FMT_CONSTEXPR void on_error(const char* message) {
2646
- throw_format_error(message);
2766
+ FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) {
2767
+ report_error(message);
2647
2768
  }
2648
2769
  };
2649
2770
 
2771
+ // A base class for compile-time strings.
2772
+ struct compile_string {};
2773
+
2774
+ template <typename S>
2775
+ using is_compile_string = std::is_base_of<compile_string, S>;
2776
+
2650
2777
  // Reports a compile-time error if S is not a valid format string.
2651
2778
  template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)>
2652
- FMT_INLINE void check_format_string(const S&) {
2779
+ FMT_ALWAYS_INLINE void check_format_string(const S&) {
2653
2780
  #ifdef FMT_ENFORCE_COMPILE_STRING
2654
2781
  static_assert(is_compile_string<S>::value,
2655
2782
  "FMT_ENFORCE_COMPILE_STRING requires all format strings to use "
@@ -2666,47 +2793,47 @@ void check_format_string(S format_str) {
2666
2793
  ignore_unused(error);
2667
2794
  }
2668
2795
 
2796
+ // Report truncation to prevent silent data loss.
2797
+ inline void report_truncation(bool truncated) {
2798
+ if (truncated) report_error("output is truncated");
2799
+ }
2800
+
2801
+ // Use vformat_args and avoid type_identity to keep symbols short and workaround
2802
+ // a GCC <= 4.8 bug.
2669
2803
  template <typename Char = char> struct vformat_args {
2670
- using type = basic_format_args<
2671
- basic_format_context<std::back_insert_iterator<buffer<Char>>, Char>>;
2804
+ using type = basic_format_args<buffered_context<Char>>;
2805
+ };
2806
+ template <> struct vformat_args<char> {
2807
+ using type = format_args;
2672
2808
  };
2673
- template <> struct vformat_args<char> { using type = format_args; };
2674
2809
 
2675
- // Use vformat_args and avoid type_identity to keep symbols short.
2676
2810
  template <typename Char>
2677
2811
  void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
2678
2812
  typename vformat_args<Char>::type args, locale_ref loc = {});
2679
2813
 
2680
- FMT_API void vprint_mojibake(std::FILE*, string_view, format_args);
2814
+ FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool = false);
2681
2815
  #ifndef _WIN32
2682
- inline void vprint_mojibake(std::FILE*, string_view, format_args) {}
2816
+ inline void vprint_mojibake(FILE*, string_view, format_args, bool) {}
2683
2817
  #endif
2684
- } // namespace detail
2685
-
2686
- FMT_BEGIN_EXPORT
2687
2818
 
2688
- // A formatter specialization for natively supported types.
2689
- template <typename T, typename Char>
2690
- struct formatter<T, Char,
2691
- enable_if_t<detail::type_constant<T, Char>::value !=
2692
- detail::type::custom_type>> {
2819
+ template <typename T, typename Char, type TYPE> struct native_formatter {
2693
2820
  private:
2694
- detail::dynamic_format_specs<Char> specs_;
2821
+ dynamic_format_specs<Char> specs_;
2695
2822
 
2696
2823
  public:
2824
+ using nonlocking = void;
2825
+
2697
2826
  template <typename ParseContext>
2698
2827
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
2699
- auto type = detail::type_constant<T, Char>::value;
2700
- auto end =
2701
- detail::parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, type);
2702
- if (type == detail::type::char_type) detail::check_char_specs(specs_);
2828
+ if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
2829
+ auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE);
2830
+ if (const_check(TYPE == type::char_type)) check_char_specs(specs_);
2703
2831
  return end;
2704
2832
  }
2705
2833
 
2706
- template <detail::type U = detail::type_constant<T, Char>::value,
2707
- FMT_ENABLE_IF(U == detail::type::string_type ||
2708
- U == detail::type::cstring_type ||
2709
- U == detail::type::char_type)>
2834
+ template <type U = TYPE,
2835
+ FMT_ENABLE_IF(U == type::string_type || U == type::cstring_type ||
2836
+ U == type::char_type)>
2710
2837
  FMT_CONSTEXPR void set_debug_format(bool set = true) {
2711
2838
  specs_.type = set ? presentation_type::debug : presentation_type::none;
2712
2839
  }
@@ -2715,27 +2842,41 @@ struct formatter<T, Char,
2715
2842
  FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
2716
2843
  -> decltype(ctx.out());
2717
2844
  };
2845
+ } // namespace detail
2846
+
2847
+ FMT_BEGIN_EXPORT
2848
+
2849
+ // A formatter specialization for natively supported types.
2850
+ template <typename T, typename Char>
2851
+ struct formatter<T, Char,
2852
+ enable_if_t<detail::type_constant<T, Char>::value !=
2853
+ detail::type::custom_type>>
2854
+ : detail::native_formatter<T, Char, detail::type_constant<T, Char>::value> {
2855
+ };
2718
2856
 
2719
2857
  template <typename Char = char> struct runtime_format_string {
2720
2858
  basic_string_view<Char> str;
2721
2859
  };
2722
2860
 
2723
- /** A compile-time format string. */
2861
+ /// A compile-time format string.
2724
2862
  template <typename Char, typename... Args> class basic_format_string {
2725
2863
  private:
2726
2864
  basic_string_view<Char> str_;
2727
2865
 
2728
2866
  public:
2729
- template <typename S,
2730
- FMT_ENABLE_IF(
2731
- std::is_convertible<const S&, basic_string_view<Char>>::value)>
2732
- FMT_CONSTEVAL FMT_INLINE basic_format_string(const S& s) : str_(s) {
2867
+ template <
2868
+ typename S,
2869
+ FMT_ENABLE_IF(
2870
+ std::is_convertible<const S&, basic_string_view<Char>>::value ||
2871
+ (detail::is_compile_string<S>::value &&
2872
+ std::is_constructible<basic_string_view<Char>, const S&>::value))>
2873
+ FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_format_string(const S& s) : str_(s) {
2733
2874
  static_assert(
2734
2875
  detail::count<
2735
2876
  (std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
2736
2877
  std::is_reference<Args>::value)...>() == 0,
2737
2878
  "passing views as lvalues is disallowed");
2738
- #ifdef FMT_HAS_CONSTEVAL
2879
+ #if FMT_USE_CONSTEVAL
2739
2880
  if constexpr (detail::count_named_args<Args...>() ==
2740
2881
  detail::count_statically_named_args<Args...>()) {
2741
2882
  using checker =
@@ -2748,8 +2889,8 @@ template <typename Char, typename... Args> class basic_format_string {
2748
2889
  }
2749
2890
  basic_format_string(runtime_format_string<Char> fmt) : str_(fmt.str) {}
2750
2891
 
2751
- FMT_INLINE operator basic_string_view<Char>() const { return str_; }
2752
- FMT_INLINE auto get() const -> basic_string_view<Char> { return str_; }
2892
+ FMT_ALWAYS_INLINE operator basic_string_view<Char>() const { return str_; }
2893
+ auto get() const -> basic_string_view<Char> { return str_; }
2753
2894
  };
2754
2895
 
2755
2896
  #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
@@ -2760,69 +2901,49 @@ inline auto runtime(string_view s) -> string_view { return s; }
2760
2901
  template <typename... Args>
2761
2902
  using format_string = basic_format_string<char, type_identity_t<Args>...>;
2762
2903
  /**
2763
- \rst
2764
- Creates a runtime format string.
2765
-
2766
- **Example**::
2767
-
2768
- // Check format string at runtime instead of compile-time.
2769
- fmt::print(fmt::runtime("{:d}"), "I am not a number");
2770
- \endrst
2904
+ * Creates a runtime format string.
2905
+ *
2906
+ * **Example**:
2907
+ *
2908
+ * // Check format string at runtime instead of compile-time.
2909
+ * fmt::print(fmt::runtime("{:d}"), "I am not a number");
2771
2910
  */
2772
2911
  inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
2773
2912
  #endif
2774
2913
 
2775
- FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
2776
-
2777
- /**
2778
- \rst
2779
- Formats ``args`` according to specifications in ``fmt`` and returns the result
2780
- as a string.
2781
-
2782
- **Example**::
2783
-
2784
- #include <fmt/core.h>
2785
- std::string message = fmt::format("The answer is {}.", 42);
2786
- \endrst
2787
- */
2788
- template <typename... T>
2789
- FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
2790
- -> std::string {
2791
- return vformat(fmt, fmt::make_format_args(args...));
2792
- }
2793
-
2794
- /** Formats a string and writes the output to ``out``. */
2914
+ /// Formats a string and writes the output to `out`.
2795
2915
  template <typename OutputIt,
2796
- FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
2797
- auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
2916
+ FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
2917
+ char>::value)>
2918
+ auto vformat_to(OutputIt&& out, string_view fmt, format_args args)
2919
+ -> remove_cvref_t<OutputIt> {
2798
2920
  auto&& buf = detail::get_buffer<char>(out);
2799
2921
  detail::vformat_to(buf, fmt, args, {});
2800
2922
  return detail::get_iterator(buf, out);
2801
2923
  }
2802
2924
 
2803
2925
  /**
2804
- \rst
2805
- Formats ``args`` according to specifications in ``fmt``, writes the result to
2806
- the output iterator ``out`` and returns the iterator past the end of the output
2807
- range. `format_to` does not append a terminating null character.
2808
-
2809
- **Example**::
2810
-
2811
- auto out = std::vector<char>();
2812
- fmt::format_to(std::back_inserter(out), "{}", 42);
2813
- \endrst
2926
+ * Formats `args` according to specifications in `fmt`, writes the result to
2927
+ * the output iterator `out` and returns the iterator past the end of the output
2928
+ * range. `format_to` does not append a terminating null character.
2929
+ *
2930
+ * **Example**:
2931
+ *
2932
+ * auto out = std::vector<char>();
2933
+ * fmt::format_to(std::back_inserter(out), "{}", 42);
2814
2934
  */
2815
2935
  template <typename OutputIt, typename... T,
2816
- FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
2817
- FMT_INLINE auto format_to(OutputIt out, format_string<T...> fmt, T&&... args)
2818
- -> OutputIt {
2819
- return vformat_to(out, fmt, fmt::make_format_args(args...));
2936
+ FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
2937
+ char>::value)>
2938
+ FMT_INLINE auto format_to(OutputIt&& out, format_string<T...> fmt, T&&... args)
2939
+ -> remove_cvref_t<OutputIt> {
2940
+ return vformat_to(FMT_FWD(out), fmt, fmt::make_format_args(args...));
2820
2941
  }
2821
2942
 
2822
2943
  template <typename OutputIt> struct format_to_n_result {
2823
- /** Iterator past the end of the output range. */
2944
+ /// Iterator past the end of the output range.
2824
2945
  OutputIt out;
2825
- /** Total (not truncated) output size. */
2946
+ /// Total (not truncated) output size.
2826
2947
  size_t size;
2827
2948
  };
2828
2949
 
@@ -2837,12 +2958,10 @@ auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)
2837
2958
  }
2838
2959
 
2839
2960
  /**
2840
- \rst
2841
- Formats ``args`` according to specifications in ``fmt``, writes up to ``n``
2842
- characters of the result to the output iterator ``out`` and returns the total
2843
- (not truncated) output size and the iterator past the end of the output range.
2844
- `format_to_n` does not append a terminating null character.
2845
- \endrst
2961
+ * Formats `args` according to specifications in `fmt`, writes up to `n`
2962
+ * characters of the result to the output iterator `out` and returns the total
2963
+ * (not truncated) output size and the iterator past the end of the output
2964
+ * range. `format_to_n` does not append a terminating null character.
2846
2965
  */
2847
2966
  template <typename OutputIt, typename... T,
2848
2967
  FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
@@ -2851,7 +2970,42 @@ FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,
2851
2970
  return vformat_to_n(out, n, fmt, fmt::make_format_args(args...));
2852
2971
  }
2853
2972
 
2854
- /** Returns the number of chars in the output of ``format(fmt, args...)``. */
2973
+ template <typename OutputIt, typename Sentinel = OutputIt>
2974
+ struct format_to_result {
2975
+ /// Iterator pointing to just after the last successful write in the range.
2976
+ OutputIt out;
2977
+ /// Specifies if the output was truncated.
2978
+ bool truncated;
2979
+
2980
+ FMT_CONSTEXPR operator OutputIt&() & {
2981
+ detail::report_truncation(truncated);
2982
+ return out;
2983
+ }
2984
+ FMT_CONSTEXPR operator const OutputIt&() const& {
2985
+ detail::report_truncation(truncated);
2986
+ return out;
2987
+ }
2988
+ FMT_CONSTEXPR operator OutputIt&&() && {
2989
+ detail::report_truncation(truncated);
2990
+ return static_cast<OutputIt&&>(out);
2991
+ }
2992
+ };
2993
+
2994
+ template <size_t N>
2995
+ auto vformat_to(char (&out)[N], string_view fmt, format_args args)
2996
+ -> format_to_result<char*> {
2997
+ auto result = vformat_to_n(out, N, fmt, args);
2998
+ return {result.out, result.size > N};
2999
+ }
3000
+
3001
+ template <size_t N, typename... T>
3002
+ FMT_INLINE auto format_to(char (&out)[N], format_string<T...> fmt, T&&... args)
3003
+ -> format_to_result<char*> {
3004
+ auto result = fmt::format_to_n(out, N, fmt, static_cast<T&&>(args)...);
3005
+ return {result.out, result.size > N};
3006
+ }
3007
+
3008
+ /// Returns the number of chars in the output of `format(fmt, args...)`.
2855
3009
  template <typename... T>
2856
3010
  FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
2857
3011
  T&&... args) -> size_t {
@@ -2861,58 +3015,56 @@ FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
2861
3015
  }
2862
3016
 
2863
3017
  FMT_API void vprint(string_view fmt, format_args args);
2864
- FMT_API void vprint(std::FILE* f, string_view fmt, format_args args);
3018
+ FMT_API void vprint(FILE* f, string_view fmt, format_args args);
3019
+ FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args);
3020
+ FMT_API void vprintln(FILE* f, string_view fmt, format_args args);
2865
3021
 
2866
3022
  /**
2867
- \rst
2868
- Formats ``args`` according to specifications in ``fmt`` and writes the output
2869
- to ``stdout``.
2870
-
2871
- **Example**::
2872
-
2873
- fmt::print("Elapsed time: {0:.2f} seconds", 1.23);
2874
- \endrst
3023
+ * Formats `args` according to specifications in `fmt` and writes the output
3024
+ * to `stdout`.
3025
+ *
3026
+ * **Example**:
3027
+ *
3028
+ * fmt::print("The answer is {}.", 42);
2875
3029
  */
2876
3030
  template <typename... T>
2877
3031
  FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
2878
3032
  const auto& vargs = fmt::make_format_args(args...);
2879
- return detail::is_utf8() ? vprint(fmt, vargs)
2880
- : detail::vprint_mojibake(stdout, fmt, vargs);
3033
+ if (!detail::use_utf8()) return detail::vprint_mojibake(stdout, fmt, vargs);
3034
+ return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt, vargs)
3035
+ : vprint(fmt, vargs);
2881
3036
  }
2882
3037
 
2883
3038
  /**
2884
- \rst
2885
- Formats ``args`` according to specifications in ``fmt`` and writes the
2886
- output to the file ``f``.
2887
-
2888
- **Example**::
2889
-
2890
- fmt::print(stderr, "Don't {}!", "panic");
2891
- \endrst
3039
+ * Formats `args` according to specifications in `fmt` and writes the
3040
+ * output to the file `f`.
3041
+ *
3042
+ * **Example**:
3043
+ *
3044
+ * fmt::print(stderr, "Don't {}!", "panic");
2892
3045
  */
2893
3046
  template <typename... T>
2894
- FMT_INLINE void print(std::FILE* f, format_string<T...> fmt, T&&... args) {
3047
+ FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
2895
3048
  const auto& vargs = fmt::make_format_args(args...);
2896
- return detail::is_utf8() ? vprint(f, fmt, vargs)
2897
- : detail::vprint_mojibake(f, fmt, vargs);
3049
+ if (!detail::use_utf8()) return detail::vprint_mojibake(f, fmt, vargs);
3050
+ return detail::is_locking<T...>() ? vprint_buffered(f, fmt, vargs)
3051
+ : vprint(f, fmt, vargs);
2898
3052
  }
2899
3053
 
2900
- /**
2901
- Formats ``args`` according to specifications in ``fmt`` and writes the
2902
- output to the file ``f`` followed by a newline.
2903
- */
3054
+ /// Formats `args` according to specifications in `fmt` and writes the output
3055
+ /// to the file `f` followed by a newline.
2904
3056
  template <typename... T>
2905
- FMT_INLINE void println(std::FILE* f, format_string<T...> fmt, T&&... args) {
2906
- return fmt::print(f, "{}\n", fmt::format(fmt, std::forward<T>(args)...));
3057
+ FMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {
3058
+ const auto& vargs = fmt::make_format_args(args...);
3059
+ return detail::use_utf8() ? vprintln(f, fmt, vargs)
3060
+ : detail::vprint_mojibake(f, fmt, vargs, true);
2907
3061
  }
2908
3062
 
2909
- /**
2910
- Formats ``args`` according to specifications in ``fmt`` and writes the output
2911
- to ``stdout`` followed by a newline.
2912
- */
3063
+ /// Formats `args` according to specifications in `fmt` and writes the output
3064
+ /// to `stdout` followed by a newline.
2913
3065
  template <typename... T>
2914
3066
  FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
2915
- return fmt::println(stdout, fmt, std::forward<T>(args)...);
3067
+ return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
2916
3068
  }
2917
3069
 
2918
3070
  FMT_END_EXPORT
@@ -2922,4 +3074,4 @@ FMT_END_NAMESPACE
2922
3074
  #ifdef FMT_HEADER_ONLY
2923
3075
  # include "format.h"
2924
3076
  #endif
2925
- #endif // FMT_CORE_H_
3077
+ #endif // FMT_BASE_H_