react-native-windows 0.81.34 → 0.81.37

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 (928) 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/Fabric/Composition/TooltipService.cpp +48 -2
  8. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +40 -13
  9. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -7
  10. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -3
  11. package/Microsoft.ReactNative/TurboModulesProvider.cpp +30 -13
  12. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  13. package/PropertySheets/React.Cpp.props +3 -3
  14. package/ReactCommon/ReactCommon.vcxproj +0 -10
  15. package/ReactCommon/packages.lock.win32.json +0 -10
  16. package/Scripts/Tfs/Layout-Desktop-Headers.ps1 +4 -37
  17. package/Scripts/creaternwlib.cmd +2 -2
  18. package/Shared/Shared.vcxitems +2 -0
  19. package/{Folly → external}/.clang-format +0 -1
  20. package/external/External.vcxitems +10 -0
  21. package/external/fast-float/.syncignore +10 -0
  22. package/external/fast-float/LICENSE-APACHE +190 -0
  23. package/external/fast-float/LICENSE-BOOST +23 -0
  24. package/external/fast-float/LICENSE-MIT +27 -0
  25. package/external/fast-float/README.md +545 -0
  26. package/external/fast-float/cgmanifest.json +15 -0
  27. package/external/fast-float/fast-float.vcxitems +14 -0
  28. package/external/fast-float/include/fast_float/ascii_number.h +588 -0
  29. package/external/fast-float/include/fast_float/bigint.h +638 -0
  30. package/external/fast-float/include/fast_float/constexpr_feature_detect.h +46 -0
  31. package/external/fast-float/include/fast_float/decimal_to_binary.h +212 -0
  32. package/external/fast-float/include/fast_float/digit_comparison.h +457 -0
  33. package/external/fast-float/include/fast_float/fast_float.h +59 -0
  34. package/external/fast-float/include/fast_float/fast_table.h +708 -0
  35. package/external/fast-float/include/fast_float/float_common.h +1240 -0
  36. package/external/fast-float/include/fast_float/parse_number.h +399 -0
  37. package/external/fast-float/sync-config.json +8 -0
  38. package/external/fmt/.syncignore +10 -0
  39. package/external/fmt/CONTRIBUTING.md +20 -0
  40. package/external/fmt/LICENSE +27 -0
  41. package/external/fmt/README.md +484 -0
  42. package/{fmt → external/fmt}/cgmanifest.json +1 -1
  43. package/external/fmt/doc/ChangeLog-old.md +3290 -0
  44. package/external/fmt/doc/api.md +650 -0
  45. package/external/fmt/doc/fmt.css +61 -0
  46. package/external/fmt/doc/fmt.js +4 -0
  47. package/external/fmt/doc/get-started.md +222 -0
  48. package/external/fmt/doc/index.md +151 -0
  49. package/external/fmt/doc/perf.svg +1 -0
  50. package/external/fmt/doc/python-license.txt +290 -0
  51. package/external/fmt/doc/syntax.md +887 -0
  52. package/external/fmt/fmt.vcxitems +28 -0
  53. package/external/fmt/include/fmt/args.h +228 -0
  54. package/{fmt/TEMP_UntilFmtUpdate/core.h → external/fmt/include/fmt/base.h} +1188 -1036
  55. package/external/fmt/include/fmt/chrono.h +2432 -0
  56. package/external/fmt/include/fmt/color.h +612 -0
  57. package/external/fmt/include/fmt/compile.h +529 -0
  58. package/external/fmt/include/fmt/core.h +5 -0
  59. package/external/fmt/include/fmt/format-inl.h +1928 -0
  60. package/external/fmt/include/fmt/format.h +4427 -0
  61. package/external/fmt/include/fmt/os.h +439 -0
  62. package/external/fmt/include/fmt/ostream.h +211 -0
  63. package/external/fmt/include/fmt/printf.h +656 -0
  64. package/external/fmt/include/fmt/ranges.h +882 -0
  65. package/external/fmt/include/fmt/std.h +699 -0
  66. package/external/fmt/include/fmt/xchar.h +322 -0
  67. package/external/fmt/src/fmt.cc +135 -0
  68. package/external/fmt/src/format.cc +43 -0
  69. package/external/fmt/src/os.cc +403 -0
  70. package/external/fmt/sync-config.json +8 -0
  71. package/external/folly/.syncignore +60 -0
  72. package/external/folly/LICENSE +200 -0
  73. package/external/folly/README.md +263 -0
  74. package/{fmt → external/folly/folly}/.clang-format +0 -1
  75. package/external/folly/folly/AtomicHashArray-inl.h +546 -0
  76. package/external/folly/folly/AtomicHashArray.h +431 -0
  77. package/external/folly/folly/AtomicHashMap-inl.h +653 -0
  78. package/external/folly/folly/AtomicHashMap.h +484 -0
  79. package/external/folly/folly/AtomicIntrusiveLinkedList.h +206 -0
  80. package/external/folly/folly/AtomicLinkedList.h +110 -0
  81. package/external/folly/folly/AtomicUnorderedMap.h +522 -0
  82. package/external/folly/folly/BUCK +1631 -0
  83. package/external/folly/folly/BUILD_MODE.bzl +72 -0
  84. package/external/folly/folly/Benchmark.cpp +986 -0
  85. package/external/folly/folly/Benchmark.h +680 -0
  86. package/external/folly/folly/BenchmarkUtil.h +47 -0
  87. package/external/folly/folly/Bits.h +17 -0
  88. package/external/folly/folly/CMakeLists.txt +110 -0
  89. package/external/folly/folly/CPortability.h +338 -0
  90. package/external/folly/folly/CancellationToken-inl.h +449 -0
  91. package/external/folly/folly/CancellationToken.cpp +250 -0
  92. package/external/folly/folly/CancellationToken.h +365 -0
  93. package/external/folly/folly/Chrono.h +132 -0
  94. package/external/folly/folly/ClockGettimeWrappers.cpp +93 -0
  95. package/external/folly/folly/ClockGettimeWrappers.h +29 -0
  96. package/external/folly/folly/ConcurrentBitSet.h +157 -0
  97. package/external/folly/folly/ConcurrentLazy.h +74 -0
  98. package/external/folly/folly/ConcurrentSkipList-inl.h +341 -0
  99. package/external/folly/folly/ConcurrentSkipList.h +824 -0
  100. package/external/folly/folly/ConstructorCallbackList.h +158 -0
  101. package/external/folly/folly/Conv.h +2026 -0
  102. package/external/folly/folly/CppAttributes.h +170 -0
  103. package/external/folly/folly/CpuId.h +297 -0
  104. package/external/folly/folly/DefaultKeepAliveExecutor.h +172 -0
  105. package/external/folly/folly/Demangle.cpp +255 -0
  106. package/external/folly/folly/Demangle.h +73 -0
  107. package/external/folly/folly/DiscriminatedPtr.h +236 -0
  108. package/external/folly/folly/DynamicConverter.h +17 -0
  109. package/external/folly/folly/Exception.h +150 -0
  110. package/external/folly/folly/ExceptionString.cpp +51 -0
  111. package/external/folly/folly/ExceptionString.h +33 -0
  112. package/external/folly/folly/ExceptionWrapper-inl.h +264 -0
  113. package/external/folly/folly/ExceptionWrapper.cpp +37 -0
  114. package/external/folly/folly/ExceptionWrapper.h +377 -0
  115. package/external/folly/folly/Executor.cpp +111 -0
  116. package/external/folly/folly/Executor.h +351 -0
  117. package/external/folly/folly/Expected.h +1725 -0
  118. package/external/folly/folly/FBString.h +2888 -0
  119. package/external/folly/folly/FBVector.h +17 -0
  120. package/external/folly/folly/File.cpp +180 -0
  121. package/external/folly/folly/File.h +177 -0
  122. package/external/folly/folly/FileUtil.cpp +378 -0
  123. package/external/folly/folly/FileUtil.h +332 -0
  124. package/external/folly/folly/Fingerprint.cpp +135 -0
  125. package/external/folly/folly/Fingerprint.h +289 -0
  126. package/external/folly/folly/FixedString.h +2965 -0
  127. package/external/folly/folly/FollyMemcpy.cpp +30 -0
  128. package/external/folly/folly/FollyMemcpy.h +23 -0
  129. package/external/folly/folly/FollyMemset.cpp +29 -0
  130. package/external/folly/folly/FollyMemset.h +25 -0
  131. package/external/folly/folly/Format-inl.h +1152 -0
  132. package/external/folly/folly/Format.cpp +429 -0
  133. package/external/folly/folly/Format.h +463 -0
  134. package/external/folly/folly/FormatArg.h +285 -0
  135. package/external/folly/folly/FormatTraits.h +65 -0
  136. package/external/folly/folly/Function.h +1159 -0
  137. package/external/folly/folly/GLog.h +85 -0
  138. package/external/folly/folly/GroupVarint.cpp +153 -0
  139. package/external/folly/folly/GroupVarint.h +630 -0
  140. package/external/folly/folly/Hash.h +20 -0
  141. package/external/folly/folly/IPAddress.cpp +490 -0
  142. package/external/folly/folly/IPAddress.h +667 -0
  143. package/external/folly/folly/IPAddressException.h +82 -0
  144. package/external/folly/folly/IPAddressV4.cpp +305 -0
  145. package/external/folly/folly/IPAddressV4.h +495 -0
  146. package/external/folly/folly/IPAddressV6.cpp +541 -0
  147. package/external/folly/folly/IPAddressV6.h +627 -0
  148. package/external/folly/folly/Indestructible.h +164 -0
  149. package/external/folly/folly/IndexedMemPool.h +550 -0
  150. package/external/folly/folly/IntrusiveList.h +17 -0
  151. package/external/folly/folly/Lazy.h +142 -0
  152. package/external/folly/folly/Likely.h +76 -0
  153. package/external/folly/folly/MPMCPipeline.h +280 -0
  154. package/external/folly/folly/MPMCQueue.h +1556 -0
  155. package/external/folly/folly/MacAddress.cpp +188 -0
  156. package/external/folly/folly/MacAddress.h +260 -0
  157. package/external/folly/folly/MapUtil.h +17 -0
  158. package/external/folly/folly/Math.h +258 -0
  159. package/external/folly/folly/MaybeManagedPtr.h +120 -0
  160. package/external/folly/folly/Memory.h +900 -0
  161. package/external/folly/folly/MicroLock.cpp +76 -0
  162. package/external/folly/folly/MicroLock.h +354 -0
  163. package/external/folly/folly/MicroSpinLock.h +17 -0
  164. package/external/folly/folly/MoveWrapper.h +76 -0
  165. package/external/folly/folly/ObserverContainer.h +1026 -0
  166. package/external/folly/folly/Optional.h +743 -0
  167. package/external/folly/folly/Overload.h +325 -0
  168. package/external/folly/folly/PackedSyncPtr.h +147 -0
  169. package/external/folly/folly/Padded.h +464 -0
  170. package/external/folly/folly/Poly-inl.h +230 -0
  171. package/external/folly/folly/Poly.h +1095 -0
  172. package/external/folly/folly/PolyException.h +43 -0
  173. package/external/folly/folly/Portability.h +644 -0
  174. package/external/folly/folly/Preprocessor.h +236 -0
  175. package/external/folly/folly/ProducerConsumerQueue.h +182 -0
  176. package/external/folly/folly/RWSpinLock.h +17 -0
  177. package/external/folly/folly/Random-inl.h +86 -0
  178. package/external/folly/folly/Random.cpp +184 -0
  179. package/external/folly/folly/Random.h +434 -0
  180. package/external/folly/folly/Range.h +1772 -0
  181. package/external/folly/folly/Replaceable.h +636 -0
  182. package/external/folly/folly/ScopeGuard.cpp +29 -0
  183. package/external/folly/folly/ScopeGuard.h +420 -0
  184. package/external/folly/folly/SharedMutex.cpp +81 -0
  185. package/external/folly/folly/SharedMutex.h +1751 -0
  186. package/external/folly/folly/Singleton-inl.h +332 -0
  187. package/external/folly/folly/Singleton.cpp +512 -0
  188. package/external/folly/folly/Singleton.h +891 -0
  189. package/external/folly/folly/SingletonThreadLocal.cpp +53 -0
  190. package/external/folly/folly/SingletonThreadLocal.h +263 -0
  191. package/external/folly/folly/SocketAddress.cpp +786 -0
  192. package/external/folly/folly/SocketAddress.h +768 -0
  193. package/external/folly/folly/SpinLock.h +55 -0
  194. package/external/folly/folly/String-inl.h +668 -0
  195. package/external/folly/folly/String.cpp +777 -0
  196. package/external/folly/folly/String.h +767 -0
  197. package/external/folly/folly/Subprocess.cpp +1142 -0
  198. package/external/folly/folly/Subprocess.h +1055 -0
  199. package/external/folly/folly/Synchronized.h +1833 -0
  200. package/external/folly/folly/SynchronizedPtr.h +106 -0
  201. package/external/folly/folly/ThreadCachedInt.h +175 -0
  202. package/external/folly/folly/ThreadLocal.h +478 -0
  203. package/external/folly/folly/TimeoutQueue.cpp +78 -0
  204. package/external/folly/folly/TimeoutQueue.h +123 -0
  205. package/external/folly/folly/TokenBucket.h +673 -0
  206. package/external/folly/folly/Traits.h +1442 -0
  207. package/external/folly/folly/Try-inl.h +372 -0
  208. package/external/folly/folly/Try.cpp +23 -0
  209. package/external/folly/folly/Try.h +728 -0
  210. package/external/folly/folly/UTF8String.h +56 -0
  211. package/external/folly/folly/Unicode.cpp +201 -0
  212. package/external/folly/folly/Unicode.h +94 -0
  213. package/external/folly/folly/Unit.h +65 -0
  214. package/external/folly/folly/Uri-inl.h +101 -0
  215. package/external/folly/folly/Uri.cpp +190 -0
  216. package/external/folly/folly/Uri.h +142 -0
  217. package/external/folly/folly/Utility.h +932 -0
  218. package/external/folly/folly/VERSION +1 -0
  219. package/external/folly/folly/Varint.h +230 -0
  220. package/external/folly/folly/VirtualExecutor.h +17 -0
  221. package/external/folly/folly/algorithm/simd/BUCK +47 -0
  222. package/external/folly/folly/algorithm/simd/Contains.cpp +42 -0
  223. package/external/folly/folly/algorithm/simd/Contains.h +116 -0
  224. package/external/folly/folly/algorithm/simd/FindFixed.h +301 -0
  225. package/external/folly/folly/algorithm/simd/Ignore.h +52 -0
  226. package/external/folly/folly/algorithm/simd/Movemask.h +207 -0
  227. package/external/folly/folly/algorithm/simd/detail/BUCK +70 -0
  228. package/external/folly/folly/algorithm/simd/detail/ContainsImpl.h +91 -0
  229. package/external/folly/folly/algorithm/simd/detail/SimdAnyOf.h +83 -0
  230. package/external/folly/folly/algorithm/simd/detail/SimdForEach.h +209 -0
  231. package/external/folly/folly/algorithm/simd/detail/SimdPlatform.h +445 -0
  232. package/external/folly/folly/algorithm/simd/detail/Traits.h +125 -0
  233. package/external/folly/folly/algorithm/simd/detail/UnrollUtils.h +126 -0
  234. package/external/folly/folly/base64.h +264 -0
  235. package/external/folly/folly/chrono/BUCK +29 -0
  236. package/external/folly/folly/chrono/Clock.h +65 -0
  237. package/external/folly/folly/chrono/Conv.h +712 -0
  238. package/external/folly/folly/chrono/test/BUCK +26 -0
  239. package/external/folly/folly/chrono/test/ClockTest.cpp +68 -0
  240. package/external/folly/folly/chrono/test/ConvTest.cpp +652 -0
  241. package/external/folly/folly/concurrency/AtomicSharedPtr.h +387 -0
  242. package/external/folly/folly/concurrency/BUCK +170 -0
  243. package/external/folly/folly/concurrency/CacheLocality.h +460 -0
  244. package/external/folly/folly/concurrency/ConcurrentHashMap.h +822 -0
  245. package/external/folly/folly/concurrency/CoreCachedSharedPtr.h +232 -0
  246. package/external/folly/folly/concurrency/DeadlockDetector.cpp +27 -0
  247. package/external/folly/folly/concurrency/DeadlockDetector.h +44 -0
  248. package/external/folly/folly/concurrency/DynamicBoundedQueue.h +751 -0
  249. package/external/folly/folly/concurrency/PriorityUnboundedQueueSet.h +207 -0
  250. package/external/folly/folly/concurrency/ProcessLocalUniqueId.cpp +46 -0
  251. package/external/folly/folly/concurrency/ProcessLocalUniqueId.h +38 -0
  252. package/external/folly/folly/concurrency/SingletonRelaxedCounter.h +325 -0
  253. package/external/folly/folly/concurrency/ThreadCachedSynchronized.h +227 -0
  254. package/external/folly/folly/concurrency/UnboundedQueue.h +891 -0
  255. package/external/folly/folly/concurrency/container/BUCK +77 -0
  256. package/external/folly/folly/concurrency/container/FlatCombiningPriorityQueue.h +426 -0
  257. package/external/folly/folly/concurrency/container/LockFreeRingBuffer.h +306 -0
  258. package/external/folly/folly/concurrency/container/RelaxedConcurrentPriorityQueue.h +1212 -0
  259. package/external/folly/folly/concurrency/container/SingleWriterFixedHashMap.h +322 -0
  260. package/external/folly/folly/concurrency/container/atomic_grow_array.h +564 -0
  261. package/external/folly/folly/concurrency/container/test/BUCK +75 -0
  262. package/external/folly/folly/concurrency/container/test/FlatCombiningPriorityQueueTest.cpp +570 -0
  263. package/external/folly/folly/concurrency/container/test/LockFreeRingBufferTest.cpp +276 -0
  264. package/external/folly/folly/concurrency/container/test/RelaxedConcurrentPriorityQueueTest.cpp +1570 -0
  265. package/external/folly/folly/concurrency/container/test/SingleWriterFixedHashMapTest.cpp +401 -0
  266. package/external/folly/folly/concurrency/container/test/atomic_grow_array_test.cpp +187 -0
  267. package/external/folly/folly/concurrency/detail/AtomicSharedPtr-detail.h +212 -0
  268. package/external/folly/folly/concurrency/detail/ConcurrentHashMap-detail.h +1911 -0
  269. package/external/folly/folly/concurrency/memory/AtomicReadMostlyMainPtr.cpp +43 -0
  270. package/external/folly/folly/concurrency/memory/AtomicReadMostlyMainPtr.h +190 -0
  271. package/external/folly/folly/concurrency/memory/BUCK +53 -0
  272. package/external/folly/folly/concurrency/memory/PrimaryPtr.h +338 -0
  273. package/external/folly/folly/concurrency/memory/ReadMostlySharedPtr.h +511 -0
  274. package/external/folly/folly/concurrency/memory/TLRefCount.h +228 -0
  275. package/external/folly/folly/concurrency/memory/test/AtomicReadMostlyMainPtrBenchmark.cpp +56 -0
  276. package/external/folly/folly/concurrency/memory/test/AtomicReadMostlyMainPtrTest.cpp +454 -0
  277. package/external/folly/folly/concurrency/memory/test/BUCK +95 -0
  278. package/external/folly/folly/concurrency/memory/test/PrimaryPtrTest.cpp +303 -0
  279. package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrBenchmark.cpp +138 -0
  280. package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrStressTest.cpp +75 -0
  281. package/external/folly/folly/concurrency/memory/test/ReadMostlySharedPtrTest.cpp +378 -0
  282. package/external/folly/folly/concurrency/memory/test/RefCountBenchmark.cpp +90 -0
  283. package/external/folly/folly/concurrency/memory/test/RefCountTest.cpp +168 -0
  284. package/external/folly/folly/concurrency/test/AtomicSharedPtrCounted.h +156 -0
  285. package/external/folly/folly/concurrency/test/AtomicSharedPtrPerformance.cpp +255 -0
  286. package/external/folly/folly/concurrency/test/AtomicSharedPtrTest.cpp +257 -0
  287. package/external/folly/folly/concurrency/test/BUCK +229 -0
  288. package/external/folly/folly/concurrency/test/CacheLocalityBenchmark.cpp +392 -0
  289. package/external/folly/folly/concurrency/test/CacheLocalityTest.cpp +1229 -0
  290. package/external/folly/folly/concurrency/test/ConcurrentHashMapBench.cpp +260 -0
  291. package/external/folly/folly/concurrency/test/ConcurrentHashMapTest.cpp +1242 -0
  292. package/external/folly/folly/concurrency/test/CoreCachedSharedPtrTest.cpp +408 -0
  293. package/external/folly/folly/concurrency/test/DynamicBoundedQueueTest.cpp +984 -0
  294. package/external/folly/folly/concurrency/test/PriorityUnboundedQueueSetTest.cpp +73 -0
  295. package/external/folly/folly/concurrency/test/ProcessLocalUniqueIdTest.cpp +66 -0
  296. package/external/folly/folly/concurrency/test/SingletonRelaxedCounterBench.cpp +101 -0
  297. package/external/folly/folly/concurrency/test/SingletonRelaxedCounterTest.cpp +185 -0
  298. package/external/folly/folly/concurrency/test/ThreadCachedSynchronizedBench.cpp +76 -0
  299. package/external/folly/folly/concurrency/test/ThreadCachedSynchronizedTest.cpp +93 -0
  300. package/external/folly/folly/concurrency/test/UnboundedQueueTest.cpp +1302 -0
  301. package/external/folly/folly/container/Access.h +57 -0
  302. package/external/folly/folly/container/Array.h +87 -0
  303. package/external/folly/folly/container/BUCK +353 -0
  304. package/external/folly/folly/container/BitIterator.h +203 -0
  305. package/external/folly/folly/container/Enumerate.h +162 -0
  306. package/external/folly/folly/container/EvictingCacheMap.h +730 -0
  307. package/external/folly/folly/container/F14.md +300 -0
  308. package/external/folly/folly/container/F14Map-fwd.h +113 -0
  309. package/external/folly/folly/container/F14Map.h +2108 -0
  310. package/external/folly/folly/container/F14Set-fwd.h +95 -0
  311. package/external/folly/folly/container/F14Set.h +1603 -0
  312. package/external/folly/folly/container/FBVector.h +1711 -0
  313. package/external/folly/folly/container/Foreach-inl.h +316 -0
  314. package/external/folly/folly/container/Foreach.h +209 -0
  315. package/external/folly/folly/container/HeterogeneousAccess-fwd.h +33 -0
  316. package/external/folly/folly/container/HeterogeneousAccess.h +171 -0
  317. package/external/folly/folly/container/IntrusiveHeap.h +268 -0
  318. package/external/folly/folly/container/IntrusiveList.h +131 -0
  319. package/external/folly/folly/container/Iterator.h +843 -0
  320. package/external/folly/folly/container/MapUtil.h +376 -0
  321. package/external/folly/folly/container/Merge.h +90 -0
  322. package/external/folly/folly/container/RegexMatchCache.cpp +521 -0
  323. package/external/folly/folly/container/RegexMatchCache.h +699 -0
  324. package/external/folly/folly/container/Reserve.h +109 -0
  325. package/external/folly/folly/container/SparseByteSet.h +123 -0
  326. package/external/folly/folly/container/View.h +81 -0
  327. package/external/folly/folly/container/WeightedEvictingCacheMap.h +651 -0
  328. package/external/folly/folly/container/detail/BUCK +115 -0
  329. package/external/folly/folly/container/detail/BitIteratorDetail.h +87 -0
  330. package/external/folly/folly/container/detail/F14Defaults.h +34 -0
  331. package/external/folly/folly/container/detail/F14IntrinsicsAvailability.h +67 -0
  332. package/external/folly/folly/container/detail/F14MapFallback.h +717 -0
  333. package/external/folly/folly/container/detail/F14Mask.h +235 -0
  334. package/external/folly/folly/container/detail/F14Policy.h +1523 -0
  335. package/external/folly/folly/container/detail/F14SetFallback.h +528 -0
  336. package/external/folly/folly/container/detail/F14Table.cpp +71 -0
  337. package/external/folly/folly/container/detail/F14Table.h +2680 -0
  338. package/external/folly/folly/container/detail/Util.h +303 -0
  339. package/external/folly/folly/container/detail/tape_detail.h +135 -0
  340. package/external/folly/folly/container/detail/test/BUCK +14 -0
  341. package/external/folly/folly/container/detail/test/F14DetailTest.cpp +47 -0
  342. package/external/folly/folly/container/heap_vector_types.h +1683 -0
  343. package/external/folly/folly/container/range_traits.h +81 -0
  344. package/external/folly/folly/container/small_vector.h +1476 -0
  345. package/external/folly/folly/container/sorted_vector_types.h +1652 -0
  346. package/external/folly/folly/container/span.h +408 -0
  347. package/external/folly/folly/container/tape.h +608 -0
  348. package/external/folly/folly/container/test/.clang-tidy +12 -0
  349. package/external/folly/folly/container/test/AccessTest.cpp +138 -0
  350. package/external/folly/folly/container/test/ArrayTest.cpp +84 -0
  351. package/external/folly/folly/container/test/BUCK +568 -0
  352. package/external/folly/folly/container/test/BitIteratorBench.cpp +112 -0
  353. package/external/folly/folly/container/test/BitIteratorTest.cpp +109 -0
  354. package/external/folly/folly/container/test/EnumerateTest.cpp +294 -0
  355. package/external/folly/folly/container/test/EvictingCacheMapBench.cpp +80 -0
  356. package/external/folly/folly/container/test/EvictingCacheMapTest.cpp +842 -0
  357. package/external/folly/folly/container/test/F14AsanSupportTest.cpp +143 -0
  358. package/external/folly/folly/container/test/F14FwdTest.cpp +37 -0
  359. package/external/folly/folly/container/test/F14InterprocessTest.cpp +404 -0
  360. package/external/folly/folly/container/test/F14MapTest.cpp +2543 -0
  361. package/external/folly/folly/container/test/F14PolicyTest.cpp +49 -0
  362. package/external/folly/folly/container/test/F14SetTest.cpp +1738 -0
  363. package/external/folly/folly/container/test/F14SmallOverheads.cpp +215 -0
  364. package/external/folly/folly/container/test/F14TestUtil.h +117 -0
  365. package/external/folly/folly/container/test/FBVectorBenchmark.cpp +380 -0
  366. package/external/folly/folly/container/test/FBVectorBenchmarks.cpp.h +100 -0
  367. package/external/folly/folly/container/test/FBVectorTest.cpp +326 -0
  368. package/external/folly/folly/container/test/FBVectorTests.cpp.h +304 -0
  369. package/external/folly/folly/container/test/ForeachBenchmark.cpp +388 -0
  370. package/external/folly/folly/container/test/ForeachTest.cpp +338 -0
  371. package/external/folly/folly/container/test/HashMapsBench.cpp +458 -0
  372. package/external/folly/folly/container/test/HeterogeneousAccessTest.cpp +242 -0
  373. package/external/folly/folly/container/test/IntrusiveHeapTest.cpp +262 -0
  374. package/external/folly/folly/container/test/IteratorTest.cpp +989 -0
  375. package/external/folly/folly/container/test/MapUtilTest.cpp +365 -0
  376. package/external/folly/folly/container/test/MergeTest.cpp +66 -0
  377. package/external/folly/folly/container/test/RegexMatchCacheTest.cpp +634 -0
  378. package/external/folly/folly/container/test/ReserveTest.cpp +173 -0
  379. package/external/folly/folly/container/test/SparseByteSetBenchmark.cpp +153 -0
  380. package/external/folly/folly/container/test/SparseByteSetTest.cpp +117 -0
  381. package/external/folly/folly/container/test/TrackingTypes.h +584 -0
  382. package/external/folly/folly/container/test/UtilTest.cpp +609 -0
  383. package/external/folly/folly/container/test/WeightedEvictingCacheMapTest.cpp +800 -0
  384. package/external/folly/folly/container/test/heap_vector_types_test.cpp +1774 -0
  385. package/external/folly/folly/container/test/range_traits_test.cpp +59 -0
  386. package/external/folly/folly/container/test/small_vector_test.cpp +1571 -0
  387. package/external/folly/folly/container/test/sorted_vector_test.cpp +1589 -0
  388. package/external/folly/folly/container/test/span_test.cpp +520 -0
  389. package/external/folly/folly/container/test/tape_bench.cpp +200 -0
  390. package/external/folly/folly/container/test/tape_test.cpp +590 -0
  391. package/external/folly/folly/defs.bzl +238 -0
  392. package/external/folly/folly/detail/AsyncTrace.cpp +36 -0
  393. package/external/folly/folly/detail/AsyncTrace.h +44 -0
  394. package/external/folly/folly/detail/AtomicHashUtils.h +42 -0
  395. package/external/folly/folly/detail/AtomicUnorderedMapUtils.h +80 -0
  396. package/external/folly/folly/detail/BUCK +406 -0
  397. package/external/folly/folly/detail/DiscriminatedPtrDetail.h +172 -0
  398. package/external/folly/folly/detail/FileUtilDetail.cpp +63 -0
  399. package/external/folly/folly/detail/FileUtilDetail.h +85 -0
  400. package/external/folly/folly/detail/FileUtilVectorDetail.h +81 -0
  401. package/external/folly/folly/detail/FingerprintPolynomial.h +132 -0
  402. package/external/folly/folly/detail/Futex-inl.h +123 -0
  403. package/external/folly/folly/detail/Futex.cpp +273 -0
  404. package/external/folly/folly/detail/Futex.h +109 -0
  405. package/external/folly/folly/detail/GroupVarintDetail.h +101 -0
  406. package/external/folly/folly/detail/IPAddress.cpp +37 -0
  407. package/external/folly/folly/detail/IPAddress.h +57 -0
  408. package/external/folly/folly/detail/IPAddressSource.h +278 -0
  409. package/external/folly/folly/detail/Iterators.h +156 -0
  410. package/external/folly/folly/detail/MPMCPipelineDetail.h +122 -0
  411. package/external/folly/folly/detail/MemoryIdler.cpp +233 -0
  412. package/external/folly/folly/detail/MemoryIdler.h +216 -0
  413. package/external/folly/folly/detail/PerfScoped.cpp +112 -0
  414. package/external/folly/folly/detail/PerfScoped.h +70 -0
  415. package/external/folly/folly/detail/PolyDetail.h +921 -0
  416. package/external/folly/folly/detail/RangeCommon.cpp +55 -0
  417. package/external/folly/folly/detail/RangeCommon.h +93 -0
  418. package/external/folly/folly/detail/RangeSse42.cpp +198 -0
  419. package/external/folly/folly/detail/RangeSse42.h +30 -0
  420. package/external/folly/folly/detail/SimpleSimdStringUtils.cpp +31 -0
  421. package/external/folly/folly/detail/SimpleSimdStringUtils.h +27 -0
  422. package/external/folly/folly/detail/SimpleSimdStringUtilsImpl.h +63 -0
  423. package/external/folly/folly/detail/Singleton.h +34 -0
  424. package/external/folly/folly/detail/SlowFingerprint.h +90 -0
  425. package/external/folly/folly/detail/SocketFastOpen.cpp +175 -0
  426. package/external/folly/folly/detail/SocketFastOpen.h +89 -0
  427. package/external/folly/folly/detail/SplitStringSimd.cpp +84 -0
  428. package/external/folly/folly/detail/SplitStringSimd.h +151 -0
  429. package/external/folly/folly/detail/SplitStringSimdImpl.h +149 -0
  430. package/external/folly/folly/detail/Sse.cpp +35 -0
  431. package/external/folly/folly/detail/Sse.h +45 -0
  432. package/external/folly/folly/detail/StaticSingletonManager.cpp +119 -0
  433. package/external/folly/folly/detail/StaticSingletonManager.h +298 -0
  434. package/external/folly/folly/detail/ThreadLocalDetail.cpp +492 -0
  435. package/external/folly/folly/detail/ThreadLocalDetail.h +800 -0
  436. package/external/folly/folly/detail/TrapOnAvx512.cpp +41 -0
  437. package/external/folly/folly/detail/TrapOnAvx512.h +21 -0
  438. package/external/folly/folly/detail/TurnSequencer.h +295 -0
  439. package/external/folly/folly/detail/TypeList.h +551 -0
  440. package/external/folly/folly/detail/UniqueInstance.cpp +136 -0
  441. package/external/folly/folly/detail/UniqueInstance.h +68 -0
  442. package/external/folly/folly/detail/base64_detail/BUCK +102 -0
  443. package/external/folly/folly/detail/base64_detail/Base64Api.cpp +40 -0
  444. package/external/folly/folly/detail/base64_detail/Base64Api.h +101 -0
  445. package/external/folly/folly/detail/base64_detail/Base64Common.h +80 -0
  446. package/external/folly/folly/detail/base64_detail/Base64Constants.h +79 -0
  447. package/external/folly/folly/detail/base64_detail/Base64HiddenConstants.h +129 -0
  448. package/external/folly/folly/detail/base64_detail/Base64SWAR.cpp +161 -0
  449. package/external/folly/folly/detail/base64_detail/Base64SWAR.h +32 -0
  450. package/external/folly/folly/detail/base64_detail/Base64Scalar.h +262 -0
  451. package/external/folly/folly/detail/base64_detail/Base64Simd.h +102 -0
  452. package/external/folly/folly/detail/base64_detail/Base64_SSE4_2.cpp +42 -0
  453. package/external/folly/folly/detail/base64_detail/Base64_SSE4_2.h +33 -0
  454. package/external/folly/folly/detail/base64_detail/Base64_SSE4_2_Platform.h +167 -0
  455. package/external/folly/folly/detail/base64_detail/README.md +392 -0
  456. package/external/folly/folly/detail/base64_detail/tests/BUCK +36 -0
  457. package/external/folly/folly/detail/base64_detail/tests/Base64AgainstScalarTest.cpp +141 -0
  458. package/external/folly/folly/detail/base64_detail/tests/Base64PlatformTest.cpp +273 -0
  459. package/external/folly/folly/detail/base64_detail/tests/Base64SpecialCasesTest.cpp +555 -0
  460. package/external/folly/folly/detail/test/AsyncTraceTest.cpp +43 -0
  461. package/external/folly/folly/detail/test/BUCK +118 -0
  462. package/external/folly/folly/detail/test/FileUtilDetailTest.cpp +56 -0
  463. package/external/folly/folly/detail/test/PerfScopedTest.cpp +107 -0
  464. package/external/folly/folly/detail/test/SimpleSimdStringUtilsTest.cpp +92 -0
  465. package/external/folly/folly/detail/test/SplitStringSimdTest.cpp +242 -0
  466. package/external/folly/folly/detail/test/StaticSingletonManagerTest.cpp +121 -0
  467. package/external/folly/folly/detail/test/ThreadLocalBenchmark.cpp +116 -0
  468. package/external/folly/folly/detail/test/ThreadLocalDetailTest.cpp +194 -0
  469. package/external/folly/folly/detail/test/TrapOnAvx512TestNegative.cpp +29 -0
  470. package/external/folly/folly/detail/test/UniqueInstanceTest.cpp +60 -0
  471. package/external/folly/folly/detail/thread_local_globals.cpp +69 -0
  472. package/external/folly/folly/detail/thread_local_globals.h +36 -0
  473. package/external/folly/folly/docs/AtomicHashMap.md +134 -0
  474. package/external/folly/folly/docs/Benchmark.md +310 -0
  475. package/external/folly/folly/docs/Conv.md +291 -0
  476. package/external/folly/folly/docs/Dynamic.md +220 -0
  477. package/external/folly/folly/docs/DynamicConverter.md +71 -0
  478. package/external/folly/folly/docs/Executors.md +63 -0
  479. package/external/folly/folly/docs/FBString.md +46 -0
  480. package/external/folly/folly/docs/FBVector.md +200 -0
  481. package/external/folly/folly/docs/Fbvector--graphical_solutions.png +0 -0
  482. package/external/folly/folly/docs/Format.md +177 -0
  483. package/external/folly/folly/docs/Function.md +92 -0
  484. package/external/folly/folly/docs/Futures.md +263 -0
  485. package/external/folly/folly/docs/GroupVarint.md +46 -0
  486. package/external/folly/folly/docs/Histogram.md +104 -0
  487. package/external/folly/folly/docs/MapUtils.md +80 -0
  488. package/external/folly/folly/docs/Overview.md +263 -0
  489. package/external/folly/folly/docs/PackedSyncPtr.md +77 -0
  490. package/external/folly/folly/docs/Poly.md +500 -0
  491. package/external/folly/folly/docs/ProducerConsumerQueue.md +82 -0
  492. package/external/folly/folly/docs/Rcu.md +218 -0
  493. package/external/folly/folly/docs/SmallLocks.md +24 -0
  494. package/external/folly/folly/docs/Synchronized.md +793 -0
  495. package/external/folly/folly/docs/ThreadCachedInt.md +98 -0
  496. package/external/folly/folly/docs/ThreadLocal.md +105 -0
  497. package/external/folly/folly/docs/Traits.md +161 -0
  498. package/external/folly/folly/docs/small_vector.md +64 -0
  499. package/external/folly/folly/docs/style.css +23 -0
  500. package/external/folly/folly/dynamic-inl.h +17 -0
  501. package/external/folly/folly/dynamic.h +17 -0
  502. package/external/folly/folly/folly_extended_library.bzl +28 -0
  503. package/external/folly/folly/functional/ApplyTuple.h +204 -0
  504. package/external/folly/folly/functional/BUCK +57 -0
  505. package/external/folly/folly/functional/Invoke.h +880 -0
  506. package/external/folly/folly/functional/Partial.h +130 -0
  507. package/external/folly/folly/functional/protocol.h +203 -0
  508. package/external/folly/folly/functional/test/ApplyTupleTest.cpp +549 -0
  509. package/external/folly/folly/functional/test/BUCK +57 -0
  510. package/external/folly/folly/functional/test/InvokeTest.cpp +483 -0
  511. package/external/folly/folly/functional/test/PartialTest.cpp +141 -0
  512. package/external/folly/folly/functional/test/protocol_test.cpp +177 -0
  513. package/external/folly/folly/functional/test/traits_test.cpp +551 -0
  514. package/external/folly/folly/functional/traits.h +675 -0
  515. package/external/folly/folly/hash/BUCK +86 -0
  516. package/external/folly/folly/hash/Checksum.cpp +275 -0
  517. package/external/folly/folly/hash/Checksum.h +94 -0
  518. package/external/folly/folly/hash/FarmHash.h +46 -0
  519. package/external/folly/folly/hash/Hash.h +1045 -0
  520. package/external/folly/folly/hash/MurmurHash.h +86 -0
  521. package/external/folly/folly/hash/SpookyHashV1.cpp +391 -0
  522. package/external/folly/folly/hash/SpookyHashV1.h +307 -0
  523. package/external/folly/folly/hash/SpookyHashV2.cpp +392 -0
  524. package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/hash/SpookyHashV2.h +6 -1
  525. package/external/folly/folly/hash/detail/BUCK +26 -0
  526. package/external/folly/folly/hash/detail/ChecksumDetail.cpp +296 -0
  527. package/external/folly/folly/hash/detail/ChecksumDetail.h +137 -0
  528. package/external/folly/folly/hash/detail/Crc32CombineDetail.cpp +191 -0
  529. package/external/folly/folly/hash/detail/Crc32cDetail.cpp +303 -0
  530. package/external/folly/folly/hash/test/BUCK +132 -0
  531. package/external/folly/folly/hash/test/ChecksumBenchmark.cpp +91 -0
  532. package/external/folly/folly/hash/test/ChecksumTest.cpp +587 -0
  533. package/external/folly/folly/hash/test/FarmHashTest.cpp +41 -0
  534. package/external/folly/folly/hash/test/HashBenchmark.cpp +238 -0
  535. package/external/folly/folly/hash/test/HashTest.cpp +997 -0
  536. package/external/folly/folly/hash/test/MurmurHashTest.cpp +76 -0
  537. package/external/folly/folly/hash/test/SpookyHashV1Test.cpp +559 -0
  538. package/external/folly/folly/hash/test/SpookyHashV2Test.cpp +549 -0
  539. package/external/folly/folly/hash/test/traits_test.cpp +69 -0
  540. package/external/folly/folly/hash/traits.h +115 -0
  541. package/external/folly/folly/json/BUCK +155 -0
  542. package/external/folly/folly/json/DynamicConverter.h +464 -0
  543. package/external/folly/folly/json/DynamicParser-inl.h +316 -0
  544. package/external/folly/folly/json/DynamicParser.cpp +198 -0
  545. package/external/folly/folly/json/DynamicParser.h +394 -0
  546. package/external/folly/folly/json/JSONSchema.cpp +1030 -0
  547. package/external/folly/folly/json/JSONSchema.h +73 -0
  548. package/external/folly/folly/json/JsonMockUtil.h +73 -0
  549. package/external/folly/folly/json/JsonTestUtil.cpp +167 -0
  550. package/external/folly/folly/json/JsonTestUtil.h +88 -0
  551. package/external/folly/folly/json/bser/BUCK +24 -0
  552. package/external/folly/folly/json/bser/Bser.h +107 -0
  553. package/external/folly/folly/json/bser/Dump.cpp +253 -0
  554. package/external/folly/folly/json/bser/Load.cpp +246 -0
  555. package/external/folly/folly/json/bser/test/BUCK +14 -0
  556. package/external/folly/folly/json/bser/test/BserTest.cpp +149 -0
  557. package/external/folly/folly/json/dynamic.cpp +552 -0
  558. package/external/folly/folly/json/dynamic.h +1346 -0
  559. package/external/folly/folly/json/json.h +238 -0
  560. package/external/folly/folly/json/json_patch.cpp +325 -0
  561. package/external/folly/folly/json/json_patch.h +126 -0
  562. package/external/folly/folly/json/json_pointer.cpp +114 -0
  563. package/external/folly/folly/json/json_pointer.h +87 -0
  564. package/external/folly/folly/json/test/BUCK +147 -0
  565. package/external/folly/folly/json/test/DynamicBenchmark.cpp +146 -0
  566. package/external/folly/folly/json/test/DynamicConverterTest.cpp +518 -0
  567. package/external/folly/folly/json/test/DynamicOtherTest.cpp +344 -0
  568. package/external/folly/folly/json/test/DynamicParserTest.cpp +443 -0
  569. package/external/folly/folly/json/test/DynamicTest.cpp +1647 -0
  570. package/external/folly/folly/json/test/JSONSchemaTest.cpp +450 -0
  571. package/external/folly/folly/json/test/JsonBenchmark.cpp +264 -0
  572. package/external/folly/folly/json/test/JsonOtherTest.cpp +51 -0
  573. package/external/folly/folly/json/test/JsonTest.cpp +1153 -0
  574. package/external/folly/folly/json/test/JsonTestUtilTest.cpp +97 -0
  575. package/external/folly/folly/json/test/json_patch_test.cpp +361 -0
  576. package/external/folly/folly/json/test/json_pointer_test.cpp +58 -0
  577. package/external/folly/folly/json/tool/BUCK +13 -0
  578. package/external/folly/folly/json/tool/JSONSchemaTester.cpp +58 -0
  579. package/external/folly/folly/json.h +17 -0
  580. package/external/folly/folly/json_patch.h +17 -0
  581. package/external/folly/folly/json_pointer.h +17 -0
  582. package/external/folly/folly/lang/Access.h +29 -0
  583. package/external/folly/folly/lang/Align.h +240 -0
  584. package/external/folly/folly/lang/Aligned.h +92 -0
  585. package/external/folly/folly/lang/Assume.h +82 -0
  586. package/external/folly/folly/lang/BUCK +287 -0
  587. package/external/folly/folly/lang/Badge.h +108 -0
  588. package/external/folly/folly/lang/Bits.h +570 -0
  589. package/external/folly/folly/lang/BitsClass.h +312 -0
  590. package/external/folly/folly/lang/Builtin.h +74 -0
  591. package/external/folly/folly/lang/CArray.h +34 -0
  592. package/external/folly/folly/lang/CString.cpp +86 -0
  593. package/external/folly/folly/lang/CString.h +55 -0
  594. package/external/folly/folly/lang/Cast.h +51 -0
  595. package/external/folly/folly/lang/CheckedMath.h +253 -0
  596. package/external/folly/folly/lang/CustomizationPoint.h +58 -0
  597. package/external/folly/folly/lang/Exception.cpp +822 -0
  598. package/external/folly/folly/lang/Exception.h +716 -0
  599. package/external/folly/folly/lang/Extern.h +55 -0
  600. package/external/folly/folly/lang/Hint-inl.h +144 -0
  601. package/external/folly/folly/lang/Hint.h +238 -0
  602. package/external/folly/folly/lang/Keep.h +98 -0
  603. package/external/folly/folly/lang/New.h +124 -0
  604. package/external/folly/folly/lang/Ordering.h +140 -0
  605. package/external/folly/folly/lang/Pretty.h +159 -0
  606. package/external/folly/folly/lang/PropagateConst.h +413 -0
  607. package/external/folly/folly/lang/RValueReferenceWrapper.h +152 -0
  608. package/external/folly/folly/lang/SafeAssert.cpp +589 -0
  609. package/external/folly/folly/lang/StaticConst.h +33 -0
  610. package/external/folly/folly/lang/Thunk.h +100 -0
  611. package/external/folly/folly/lang/TypeInfo.h +58 -0
  612. package/external/folly/folly/lang/UncaughtExceptions.cpp +17 -0
  613. package/external/folly/folly/lang/UncaughtExceptions.h +19 -0
  614. package/external/folly/folly/lang/test/AlignTest.cpp +87 -0
  615. package/external/folly/folly/lang/test/AlignedTest.cpp +130 -0
  616. package/external/folly/folly/lang/test/BUCK +258 -0
  617. package/external/folly/folly/lang/test/BadgeTest.cpp +89 -0
  618. package/external/folly/folly/lang/test/BitsBenchmark.cpp +164 -0
  619. package/external/folly/folly/lang/test/BitsClassBenchmark.cpp +122 -0
  620. package/external/folly/folly/lang/test/BitsClassTest.cpp +379 -0
  621. package/external/folly/folly/lang/test/BitsTest.cpp +577 -0
  622. package/external/folly/folly/lang/test/CStringTest.cpp +60 -0
  623. package/external/folly/folly/lang/test/CastTest.cpp +47 -0
  624. package/external/folly/folly/lang/test/CheckedMathTest.cpp +394 -0
  625. package/external/folly/folly/lang/test/ExceptionBench.cpp +427 -0
  626. package/external/folly/folly/lang/test/ExceptionTest.cpp +413 -0
  627. package/external/folly/folly/lang/test/ExternTest.cpp +39 -0
  628. package/external/folly/folly/lang/test/HintTest.cpp +100 -0
  629. package/external/folly/folly/lang/test/NewTest.cpp +38 -0
  630. package/external/folly/folly/lang/test/OrderingTest.cpp +105 -0
  631. package/external/folly/folly/lang/test/PrettyTest.cpp +44 -0
  632. package/external/folly/folly/lang/test/PropagateConstTest.cpp +356 -0
  633. package/external/folly/folly/lang/test/RValueReferenceWrapperTest.cpp +85 -0
  634. package/external/folly/folly/lang/test/SafeAssertTest.cpp +75 -0
  635. package/external/folly/folly/lang/test/ThunkTest.cpp +105 -0
  636. package/external/folly/folly/lang/test/ToAsciiBench.cpp +466 -0
  637. package/external/folly/folly/lang/test/ToAsciiTest.cpp +266 -0
  638. package/external/folly/folly/lang/test/TypeInfoTest.cpp +56 -0
  639. package/external/folly/folly/memcpy.S +292 -0
  640. package/external/folly/folly/memcpy_select_aarch64.cpp +145 -0
  641. package/external/folly/folly/memory/Arena-inl.h +83 -0
  642. package/external/folly/folly/memory/Arena.h +325 -0
  643. package/external/folly/folly/memory/BUCK +191 -0
  644. package/external/folly/folly/memory/JemallocHugePageAllocator.cpp +449 -0
  645. package/external/folly/folly/memory/JemallocHugePageAllocator.h +105 -0
  646. package/external/folly/folly/memory/JemallocHugePageAllocatorTest.cpp +341 -0
  647. package/external/folly/folly/memory/JemallocNodumpAllocator.cpp +176 -0
  648. package/external/folly/folly/memory/JemallocNodumpAllocator.h +119 -0
  649. package/external/folly/folly/memory/JemallocNodumpAllocatorTest.cpp +61 -0
  650. package/external/folly/folly/memory/MallctlHelper.cpp +37 -0
  651. package/external/folly/folly/memory/MallctlHelper.h +167 -0
  652. package/external/folly/folly/memory/Malloc.h +551 -0
  653. package/external/folly/folly/memory/MemoryResource.h +57 -0
  654. package/external/folly/folly/memory/ReentrantAllocator.cpp +162 -0
  655. package/external/folly/folly/memory/ReentrantAllocator.h +261 -0
  656. package/external/folly/folly/memory/SanitizeAddress.cpp +75 -0
  657. package/external/folly/folly/memory/SanitizeAddress.h +117 -0
  658. package/external/folly/folly/memory/SanitizeLeak.cpp +119 -0
  659. package/external/folly/folly/memory/SanitizeLeak.h +108 -0
  660. package/external/folly/folly/memory/ThreadCachedArena.cpp +53 -0
  661. package/external/folly/folly/memory/ThreadCachedArena.h +90 -0
  662. package/external/folly/folly/memory/UninitializedMemoryHacks.h +426 -0
  663. package/external/folly/folly/memory/detail/BUCK +10 -0
  664. package/external/folly/folly/memory/detail/MallocImpl.cpp +52 -0
  665. package/external/folly/folly/memory/detail/MallocImpl.h +97 -0
  666. package/external/folly/folly/memory/not_null-inl.h +522 -0
  667. package/external/folly/folly/memory/not_null.h +449 -0
  668. package/external/folly/folly/memory/test/ArenaTest.cpp +354 -0
  669. package/external/folly/folly/memory/test/BUCK +146 -0
  670. package/external/folly/folly/memory/test/MallctlHelperTest.cpp +169 -0
  671. package/external/folly/folly/memory/test/MallocBenchmark.cpp +91 -0
  672. package/external/folly/folly/memory/test/MallocTest.cpp +78 -0
  673. package/external/folly/folly/memory/test/MemoryResourceTest.cpp +31 -0
  674. package/external/folly/folly/memory/test/ReentrantAllocatorTest.cpp +144 -0
  675. package/external/folly/folly/memory/test/SanitizeAddressTest.cpp +67 -0
  676. package/external/folly/folly/memory/test/SanitizeLeakTest.cpp +139 -0
  677. package/external/folly/folly/memory/test/ThreadCachedArenaTest.cpp +276 -0
  678. package/external/folly/folly/memory/test/UninitializedMemoryHacksODR.cpp +21 -0
  679. package/external/folly/folly/memory/test/UninitializedMemoryHacksTest.cpp +327 -0
  680. package/external/folly/folly/memory/test/not_null_test.cpp +608 -0
  681. package/external/folly/folly/memset.S +245 -0
  682. package/external/folly/folly/memset_select_aarch64.cpp +72 -0
  683. package/external/folly/folly/portability/Asm.h +50 -0
  684. package/external/folly/folly/portability/Atomic.h +31 -0
  685. package/external/folly/folly/portability/BUCK +456 -0
  686. package/external/folly/folly/portability/Builtins.cpp +31 -0
  687. package/external/folly/folly/portability/Builtins.h +161 -0
  688. package/external/folly/folly/portability/Config.h +43 -0
  689. package/external/folly/folly/portability/Constexpr.h +145 -0
  690. package/external/folly/folly/portability/Dirent.cpp +140 -0
  691. package/external/folly/folly/portability/Dirent.h +41 -0
  692. package/external/folly/folly/portability/Event.h +44 -0
  693. package/external/folly/folly/portability/Fcntl.cpp +120 -0
  694. package/external/folly/folly/portability/Fcntl.h +67 -0
  695. package/external/folly/folly/portability/Filesystem.cpp +67 -0
  696. package/external/folly/folly/portability/Filesystem.h +114 -0
  697. package/external/folly/folly/portability/FmtCompile.h +40 -0
  698. package/external/folly/folly/portability/GFlags.h +139 -0
  699. package/external/folly/folly/portability/GMock.h +35 -0
  700. package/external/folly/folly/portability/GTest.h +35 -0
  701. package/external/folly/folly/portability/IOVec.h +34 -0
  702. package/external/folly/folly/portability/Libgen.cpp +59 -0
  703. package/external/folly/folly/portability/Libgen.h +29 -0
  704. package/external/folly/folly/portability/Libunwind.h +21 -0
  705. package/external/folly/folly/portability/Malloc.cpp +31 -0
  706. package/external/folly/folly/portability/Malloc.h +53 -0
  707. package/external/folly/folly/portability/Math.h +90 -0
  708. package/external/folly/folly/portability/Memory.h +26 -0
  709. package/external/folly/folly/portability/OpenSSL.cpp +17 -0
  710. package/external/folly/folly/portability/OpenSSL.h +102 -0
  711. package/external/folly/folly/portability/PThread.cpp +697 -0
  712. package/external/folly/folly/portability/PThread.h +148 -0
  713. package/external/folly/folly/portability/README.md +21 -0
  714. package/external/folly/folly/portability/Sched.cpp +41 -0
  715. package/external/folly/folly/portability/Sched.h +45 -0
  716. package/external/folly/folly/portability/Sockets.cpp +245 -0
  717. package/external/folly/folly/portability/Sockets.h +155 -0
  718. package/external/folly/folly/portability/SourceLocation.h +49 -0
  719. package/external/folly/folly/portability/Stdio.cpp +77 -0
  720. package/external/folly/folly/portability/Stdio.h +32 -0
  721. package/external/folly/folly/portability/Stdlib.cpp +172 -0
  722. package/external/folly/folly/portability/Stdlib.h +64 -0
  723. package/external/folly/folly/portability/String.cpp +53 -0
  724. package/external/folly/folly/portability/String.h +39 -0
  725. package/external/folly/folly/portability/SysFile.cpp +46 -0
  726. package/external/folly/folly/portability/SysFile.h +27 -0
  727. package/external/folly/folly/portability/SysMembarrier.cpp +104 -0
  728. package/external/folly/folly/portability/SysMembarrier.h +26 -0
  729. package/external/folly/folly/portability/SysMman.cpp +242 -0
  730. package/external/folly/folly/portability/SysMman.h +68 -0
  731. package/external/folly/folly/portability/SysResource.cpp +108 -0
  732. package/external/folly/folly/portability/SysResource.h +71 -0
  733. package/external/folly/folly/portability/SysStat.cpp +66 -0
  734. package/external/folly/folly/portability/SysStat.h +52 -0
  735. package/external/folly/folly/portability/SysSyscall.h +73 -0
  736. package/external/folly/folly/portability/SysTime.cpp +62 -0
  737. package/external/folly/folly/portability/SysTime.h +50 -0
  738. package/external/folly/folly/portability/SysTypes.h +44 -0
  739. package/external/folly/folly/portability/SysUio.cpp +179 -0
  740. package/external/folly/folly/portability/SysUio.h +51 -0
  741. package/external/folly/folly/portability/Syslog.h +39 -0
  742. package/external/folly/folly/portability/Time.cpp +357 -0
  743. package/external/folly/folly/portability/Time.h +74 -0
  744. package/external/folly/folly/portability/Unistd.h +111 -0
  745. package/external/folly/folly/portability/Windows.h +108 -0
  746. package/external/folly/folly/portability/openat2.c +30 -0
  747. package/external/folly/folly/portability/openat2.h +39 -0
  748. package/external/folly/folly/portability/test/BUCK +59 -0
  749. package/external/folly/folly/portability/test/ConstexprTest.cpp +102 -0
  750. package/external/folly/folly/portability/test/FilesystemTest.cpp +35 -0
  751. package/external/folly/folly/portability/test/LibgenTest.cpp +35 -0
  752. package/external/folly/folly/portability/test/OpenSSLPortabilityTest.cpp +108 -0
  753. package/external/folly/folly/portability/test/PThreadTest.cpp +80 -0
  754. package/external/folly/folly/portability/test/TimeTest.cpp +90 -0
  755. package/external/folly/folly/small_vector.h +17 -0
  756. package/external/folly/folly/somerge_defs.bzl +399 -0
  757. package/external/folly/folly/sorted_vector_types.h +17 -0
  758. package/external/folly/folly/stop_watch.h +317 -0
  759. package/external/folly/folly/synchronization/AsymmetricThreadFence.cpp +91 -0
  760. package/external/folly/folly/synchronization/AsymmetricThreadFence.h +60 -0
  761. package/external/folly/folly/synchronization/AtomicNotification-inl.h +146 -0
  762. package/external/folly/folly/synchronization/AtomicNotification.cpp +34 -0
  763. package/external/folly/folly/synchronization/AtomicNotification.h +117 -0
  764. package/external/folly/folly/synchronization/AtomicRef.h +181 -0
  765. package/external/folly/folly/synchronization/AtomicStruct.h +150 -0
  766. package/external/folly/folly/synchronization/AtomicUtil-inl.h +482 -0
  767. package/external/folly/folly/synchronization/AtomicUtil.h +179 -0
  768. package/external/folly/folly/synchronization/BUCK +418 -0
  769. package/external/folly/folly/synchronization/Baton.h +419 -0
  770. package/external/folly/folly/synchronization/CallOnce.h +263 -0
  771. package/external/folly/folly/synchronization/DelayedInit.h +179 -0
  772. package/external/folly/folly/synchronization/DistributedMutex-inl.h +1744 -0
  773. package/external/folly/folly/synchronization/DistributedMutex.cpp +27 -0
  774. package/external/folly/folly/synchronization/DistributedMutex.h +342 -0
  775. package/external/folly/folly/synchronization/EventCount.h +200 -0
  776. package/external/folly/folly/synchronization/FlatCombining.h +629 -0
  777. package/external/folly/folly/synchronization/Hazptr-fwd.h +217 -0
  778. package/external/folly/folly/synchronization/Hazptr.cpp +36 -0
  779. package/external/folly/folly/synchronization/Hazptr.h +209 -0
  780. package/external/folly/folly/synchronization/HazptrDomain.cpp +68 -0
  781. package/external/folly/folly/synchronization/HazptrDomain.h +832 -0
  782. package/external/folly/folly/synchronization/HazptrHolder.h +431 -0
  783. package/external/folly/folly/synchronization/HazptrObj.h +533 -0
  784. package/external/folly/folly/synchronization/HazptrObjLinked.h +315 -0
  785. package/external/folly/folly/synchronization/HazptrRec.h +68 -0
  786. package/external/folly/folly/synchronization/HazptrThrLocal.h +180 -0
  787. package/external/folly/folly/synchronization/HazptrThreadPoolExecutor.cpp +46 -0
  788. package/external/folly/folly/synchronization/HazptrThreadPoolExecutor.h +25 -0
  789. package/external/folly/folly/synchronization/Latch.h +160 -0
  790. package/external/folly/folly/synchronization/LifoSem.h +767 -0
  791. package/external/folly/folly/synchronization/Lock.h +887 -0
  792. package/external/folly/folly/synchronization/MicroSpinLock.h +154 -0
  793. package/external/folly/folly/synchronization/NativeSemaphore.h +187 -0
  794. package/external/folly/folly/synchronization/ParkingLot.cpp +37 -0
  795. package/external/folly/folly/synchronization/ParkingLot.h +330 -0
  796. package/external/folly/folly/synchronization/PicoSpinLock.h +167 -0
  797. package/external/folly/folly/synchronization/RWSpinLock.h +549 -0
  798. package/external/folly/folly/synchronization/Rcu.cpp +26 -0
  799. package/external/folly/folly/synchronization/Rcu.h +553 -0
  800. package/external/folly/folly/synchronization/RelaxedAtomic.h +336 -0
  801. package/external/folly/folly/synchronization/SanitizeThread.cpp +141 -0
  802. package/external/folly/folly/synchronization/SanitizeThread.h +166 -0
  803. package/external/folly/folly/synchronization/SaturatingSemaphore.h +324 -0
  804. package/external/folly/folly/synchronization/SmallLocks.h +36 -0
  805. package/external/folly/folly/synchronization/ThrottledLifoSem.h +362 -0
  806. package/external/folly/folly/synchronization/WaitOptions.cpp +25 -0
  807. package/external/folly/folly/synchronization/WaitOptions.h +75 -0
  808. package/external/folly/folly/synchronization/detail/AtomicUtils.h +59 -0
  809. package/external/folly/folly/synchronization/detail/BUCK +104 -0
  810. package/external/folly/folly/synchronization/detail/Hardware.cpp +192 -0
  811. package/external/folly/folly/synchronization/detail/Hardware.h +75 -0
  812. package/external/folly/folly/synchronization/detail/HazptrUtils.h +339 -0
  813. package/external/folly/folly/synchronization/detail/InlineFunctionRef.h +229 -0
  814. package/external/folly/folly/synchronization/detail/Sleeper.cpp +27 -0
  815. package/external/folly/folly/synchronization/detail/Sleeper.h +62 -0
  816. package/external/folly/folly/synchronization/detail/Spin.h +96 -0
  817. package/external/folly/folly/synchronization/detail/ThreadCachedLists.h +174 -0
  818. package/external/folly/folly/synchronization/detail/ThreadCachedReaders.h +189 -0
  819. package/external/folly/folly/synchronization/detail/ThreadCachedTag.h +26 -0
  820. package/external/folly/folly/synchronization/detail/test/BUCK +28 -0
  821. package/external/folly/folly/synchronization/detail/test/HardwareTest.cpp +74 -0
  822. package/external/folly/folly/synchronization/detail/test/InlineFunctionRefTest.cpp +286 -0
  823. package/external/folly/folly/synchronization/example/BUCK +27 -0
  824. package/external/folly/folly/synchronization/example/HazptrLockFreeLIFO.h +88 -0
  825. package/external/folly/folly/synchronization/example/HazptrSWMRSet.h +133 -0
  826. package/external/folly/folly/synchronization/example/HazptrWideCAS.h +62 -0
  827. package/external/folly/folly/synchronization/test/AtomicNotificationTest.cpp +236 -0
  828. package/external/folly/folly/synchronization/test/AtomicRefTest.cpp +170 -0
  829. package/external/folly/folly/synchronization/test/AtomicStructTest.cpp +65 -0
  830. package/external/folly/folly/synchronization/test/AtomicUtilBench.cpp +457 -0
  831. package/external/folly/folly/synchronization/test/AtomicUtilTest.cpp +650 -0
  832. package/external/folly/folly/synchronization/test/BUCK +495 -0
  833. package/external/folly/folly/synchronization/test/Barrier.h +52 -0
  834. package/external/folly/folly/synchronization/test/BarrierTest.cpp +56 -0
  835. package/external/folly/folly/synchronization/test/BatonBenchmark.cpp +77 -0
  836. package/external/folly/folly/synchronization/test/BatonTest.cpp +164 -0
  837. package/external/folly/folly/synchronization/test/BatonTestHelpers.h +118 -0
  838. package/external/folly/folly/synchronization/test/CallOnceBenchmark.cpp +72 -0
  839. package/external/folly/folly/synchronization/test/CallOnceTest.cpp +153 -0
  840. package/external/folly/folly/synchronization/test/DelayedInitTest.cpp +281 -0
  841. package/external/folly/folly/synchronization/test/DistributedMutexTest.cpp +2074 -0
  842. package/external/folly/folly/synchronization/test/EventCountTest.cpp +124 -0
  843. package/external/folly/folly/synchronization/test/FlatCombiningBenchmark.cpp +1789 -0
  844. package/external/folly/folly/synchronization/test/FlatCombiningExamples.h +222 -0
  845. package/external/folly/folly/synchronization/test/FlatCombiningTest.cpp +121 -0
  846. package/external/folly/folly/synchronization/test/FlatCombiningTestHelpers.h +227 -0
  847. package/external/folly/folly/synchronization/test/HazptrTest.cpp +1689 -0
  848. package/external/folly/folly/synchronization/test/LatchTest.cpp +224 -0
  849. package/external/folly/folly/synchronization/test/LifoSemBench.cpp +185 -0
  850. package/external/folly/folly/synchronization/test/LifoSemTests.cpp +353 -0
  851. package/external/folly/folly/synchronization/test/LockTest.cpp +1239 -0
  852. package/external/folly/folly/synchronization/test/NativeSemaphoreTest.cpp +37 -0
  853. package/external/folly/folly/synchronization/test/ParkingLotBenchmark.cpp +239 -0
  854. package/external/folly/folly/synchronization/test/ParkingLotTest.cpp +170 -0
  855. package/external/folly/folly/synchronization/test/RWSpinLockTest.cpp +235 -0
  856. package/external/folly/folly/synchronization/test/RcuBench.cpp +66 -0
  857. package/external/folly/folly/synchronization/test/RcuTest.cpp +330 -0
  858. package/external/folly/folly/synchronization/test/RelaxedAtomicTest.cpp +389 -0
  859. package/external/folly/folly/synchronization/test/SaturatingSemaphoreTest.cpp +166 -0
  860. package/external/folly/folly/synchronization/test/Semaphore.h +242 -0
  861. package/external/folly/folly/synchronization/test/SemaphoreTest.cpp +271 -0
  862. package/external/folly/folly/synchronization/test/SmallLocksBenchmark.cpp +1296 -0
  863. package/external/folly/folly/synchronization/test/SmallLocksTest.cpp +510 -0
  864. package/external/folly/folly/synchronization/test/ThreadCachedEpochBench.h +67 -0
  865. package/external/folly/folly/synchronization/test/ThreadCachedReadersBench.cpp +42 -0
  866. package/external/folly/folly/synchronization/test/ThreadCachedReadersTest.cpp +52 -0
  867. package/external/folly/folly/synchronization/test/ThrottledLifoSemTest.cpp +243 -0
  868. package/external/folly/folly/system/AtFork.cpp +205 -0
  869. package/external/folly/folly/system/AtFork.h +116 -0
  870. package/external/folly/folly/system/AuxVector.h +198 -0
  871. package/external/folly/folly/system/BUCK +144 -0
  872. package/external/folly/folly/system/EnvUtil.cpp +93 -0
  873. package/external/folly/folly/system/EnvUtil.h +113 -0
  874. package/external/folly/folly/system/HardwareConcurrency.cpp +39 -0
  875. package/external/folly/folly/system/HardwareConcurrency.h +23 -0
  876. package/external/folly/folly/system/MemoryMapping.cpp +477 -0
  877. package/external/folly/folly/system/MemoryMapping.h +287 -0
  878. package/external/folly/folly/system/Pid.cpp +87 -0
  879. package/external/folly/folly/system/Pid.h +34 -0
  880. package/external/folly/folly/system/Shell.cpp +33 -0
  881. package/external/folly/folly/system/Shell.h +93 -0
  882. package/external/folly/folly/system/ThreadId.cpp +89 -0
  883. package/external/folly/folly/system/ThreadId.h +62 -0
  884. package/external/folly/folly/system/ThreadName.cpp +330 -0
  885. package/external/folly/folly/system/ThreadName.h +72 -0
  886. package/external/folly/folly/system/test/AtForkTest.cpp +309 -0
  887. package/external/folly/folly/system/test/AuxVectorTest.cpp +55 -0
  888. package/external/folly/folly/system/test/BUCK +120 -0
  889. package/external/folly/folly/system/test/EnvUtilSubprocess.cpp +26 -0
  890. package/external/folly/folly/system/test/EnvUtilTest.cpp +197 -0
  891. package/external/folly/folly/system/test/MemoryMappingTest.cpp +179 -0
  892. package/external/folly/folly/system/test/PidTest.cpp +46 -0
  893. package/external/folly/folly/system/test/ShellTest.cpp +66 -0
  894. package/external/folly/folly/system/test/ThreadIdTest.cpp +114 -0
  895. package/external/folly/folly/system/test/ThreadNameTest.cpp +85 -0
  896. package/external/folly/folly.vcxitems +164 -0
  897. package/external/folly/static/logo.svg +1 -0
  898. package/external/folly/sync-config.json +8 -0
  899. package/package.json +3 -3
  900. package/template/cpp-app/proj/MyApp.sln +0 -33
  901. package/template/cpp-lib/proj/MyLib.sln +0 -33
  902. package/template/cs-app/proj/MyApp.sln +0 -33
  903. package/template/cs-lib/proj/MyLib.sln +0 -33
  904. package/templates/cpp-app/windows/MyApp.sln +0 -33
  905. package/templates/cpp-lib/example/metro.config.js +31 -6
  906. package/templates/cpp-lib/windows/MyLib.sln +0 -33
  907. package/Folly/Folly.vcxproj +0 -383
  908. package/Folly/Folly.vcxproj.filters +0 -558
  909. package/Folly/Folly.win32.vcxproj +0 -11
  910. package/Folly/packages.lock.win32.json +0 -20
  911. package/Scripts/Warm-RnwFeedCache.ps1 +0 -413
  912. package/fmt/fmt.vcxproj +0 -163
  913. package/fmt/fmt.vcxproj.filters +0 -59
  914. package/fmt/fmt.win32.vcxproj +0 -10
  915. package/fmt/pch.cpp +0 -4
  916. package/fmt/pch.h +0 -2
  917. /package/{Folly → external/folly}/Folly.natvis +0 -0
  918. /package/{Folly → external/folly}/cgmanifest.json +0 -0
  919. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/ConstexprMath.h +0 -0
  920. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/Conv.cpp +0 -0
  921. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/chrono/Hardware.h +0 -0
  922. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/concurrency/CacheLocality.cpp +0 -0
  923. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/json/dynamic-inl.h +0 -0
  924. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/json/json.cpp +0 -0
  925. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/SafeAssert.h +0 -0
  926. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/ToAscii.cpp +0 -0
  927. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/lang/ToAscii.h +0 -0
  928. /package/{Folly/TEMP_UntilFollyUpdate → external/folly/folly}/portability/Unistd.cpp +0 -0
@@ -0,0 +1,2888 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ // String type.
18
+
19
+ #pragma once
20
+
21
+ #include <algorithm>
22
+ #include <atomic>
23
+ #include <cassert>
24
+ #include <cstddef>
25
+ #include <cstring>
26
+ #include <iosfwd>
27
+ #include <limits>
28
+ #include <stdexcept>
29
+ #include <string>
30
+ #include <string_view>
31
+ #include <type_traits>
32
+ #include <utility>
33
+
34
+ #include <fmt/format.h>
35
+ #include <folly/CPortability.h>
36
+ #include <folly/CppAttributes.h>
37
+ #include <folly/Likely.h>
38
+ #include <folly/Portability.h>
39
+ #include <folly/Traits.h>
40
+ #include <folly/hash/Hash.h>
41
+ #include <folly/lang/Assume.h>
42
+ #include <folly/lang/CheckedMath.h>
43
+ #include <folly/lang/Exception.h>
44
+ #include <folly/memory/Malloc.h>
45
+
46
+ #if FOLLY_CPLUSPLUS >= 202002L
47
+ #include <compare>
48
+ #endif
49
+
50
+ FOLLY_PUSH_WARNING
51
+ // Ignore shadowing warnings within this file, so includers can use -Wshadow.
52
+ FOLLY_GNU_DISABLE_WARNING("-Wshadow")
53
+
54
+ namespace folly {
55
+
56
+ // When compiling with ASan, always heap-allocate the string even if
57
+ // it would fit in-situ, so that ASan can detect access to the string
58
+ // buffer after it has been invalidated (destroyed, resized, etc.).
59
+ // Note that this flag doesn't remove support for in-situ strings, as
60
+ // that would break ABI-compatibility and wouldn't allow linking code
61
+ // compiled with this flag with code compiled without.
62
+ #ifdef FOLLY_SANITIZE_ADDRESS
63
+ #define FBSTRING_DISABLE_SSO true
64
+ #else
65
+ #define FBSTRING_DISABLE_SSO false
66
+ #endif
67
+
68
+ namespace fbstring_detail {
69
+
70
+ template <class InIt, class OutIt>
71
+ inline std::pair<InIt, OutIt> copy_n(
72
+ InIt b, typename std::iterator_traits<InIt>::difference_type n, OutIt d) {
73
+ for (; n != 0; --n, ++b, ++d) {
74
+ *d = *b;
75
+ }
76
+ return std::make_pair(b, d);
77
+ }
78
+
79
+ template <class Pod, class T>
80
+ inline void podFill(Pod* b, Pod* e, T c) {
81
+ assert(b && e && b <= e);
82
+ constexpr auto kUseMemset = sizeof(T) == 1;
83
+ if /* constexpr */ (kUseMemset) {
84
+ memset(b, c, size_t(e - b));
85
+ } else {
86
+ auto const ee = b + ((e - b) & ~7u);
87
+ for (; b != ee; b += 8) {
88
+ b[0] = c;
89
+ b[1] = c;
90
+ b[2] = c;
91
+ b[3] = c;
92
+ b[4] = c;
93
+ b[5] = c;
94
+ b[6] = c;
95
+ b[7] = c;
96
+ }
97
+ // Leftovers
98
+ for (; b != e; ++b) {
99
+ *b = c;
100
+ }
101
+ }
102
+ }
103
+
104
+ /*
105
+ * Lightly structured memcpy, simplifies copying PODs and introduces
106
+ * some asserts. Unfortunately using this function may cause
107
+ * measurable overhead (presumably because it adjusts from a begin/end
108
+ * convention to a pointer/size convention, so it does some extra
109
+ * arithmetic even though the caller might have done the inverse
110
+ * adaptation outside).
111
+ */
112
+ template <class Pod>
113
+ inline void podCopy(const Pod* b, const Pod* e, Pod* d) {
114
+ assert(b != nullptr);
115
+ assert(e != nullptr);
116
+ assert(d != nullptr);
117
+ assert(e >= b);
118
+ assert(d >= e || d + (e - b) <= b);
119
+ memcpy(d, b, (e - b) * sizeof(Pod));
120
+ }
121
+
122
+ /*
123
+ * Lightly structured memmove, simplifies copying PODs and introduces
124
+ * some asserts
125
+ */
126
+ template <class Pod>
127
+ inline void podMove(const Pod* b, const Pod* e, Pod* d) {
128
+ assert(e >= b);
129
+ memmove(d, b, (e - b) * sizeof(*b));
130
+ }
131
+ } // namespace fbstring_detail
132
+
133
+ /**
134
+ * Defines a special acquisition method for constructing fbstring
135
+ * objects. AcquireMallocatedString means that the user passes a
136
+ * pointer to a malloc-allocated string that the fbstring object will
137
+ * take into custody.
138
+ */
139
+ enum class AcquireMallocatedString {};
140
+
141
+ /*
142
+ * fbstring_core_model is a mock-up type that defines all required
143
+ * signatures of a fbstring core. The fbstring class itself uses such
144
+ * a core object to implement all of the numerous member functions
145
+ * required by the standard.
146
+ *
147
+ * If you want to define a new core, copy the definition below and
148
+ * implement the primitives. Then plug the core into basic_fbstring as
149
+ * a template argument.
150
+
151
+ template <class Char>
152
+ class fbstring_core_model {
153
+ public:
154
+ fbstring_core_model();
155
+ fbstring_core_model(const fbstring_core_model &);
156
+ fbstring_core_model& operator=(const fbstring_core_model &) = delete;
157
+ ~fbstring_core_model();
158
+ // Returns a pointer to string's buffer (currently only contiguous
159
+ // strings are supported). The pointer is guaranteed to be valid
160
+ // until the next call to a non-const member function.
161
+ const Char * data() const;
162
+ // Much like data(), except the string is prepared to support
163
+ // character-level changes. This call is a signal for
164
+ // e.g. reference-counted implementation to fork the data. The
165
+ // pointer is guaranteed to be valid until the next call to a
166
+ // non-const member function.
167
+ Char* mutableData();
168
+ // Returns a pointer to string's buffer and guarantees that a
169
+ // readable '\0' lies right after the buffer. The pointer is
170
+ // guaranteed to be valid until the next call to a non-const member
171
+ // function.
172
+ const Char * c_str() const;
173
+ // Shrinks the string by delta characters. Asserts that delta <=
174
+ // size().
175
+ void shrink(size_t delta);
176
+ // Expands the string by delta characters (i.e. after this call
177
+ // size() will report the old size() plus delta) but without
178
+ // initializing the expanded region. The expanded region is
179
+ // zero-terminated. Returns a pointer to the memory to be
180
+ // initialized (the beginning of the expanded portion). The caller
181
+ // is expected to fill the expanded area appropriately.
182
+ // If expGrowth is true, exponential growth is guaranteed.
183
+ // It is not guaranteed not to reallocate even if size() + delta <
184
+ // capacity(), so all references to the buffer are invalidated.
185
+ Char* expandNoinit(size_t delta, bool expGrowth);
186
+ // Expands the string by one character and sets the last character
187
+ // to c.
188
+ void push_back(Char c);
189
+ // Returns the string's size.
190
+ size_t size() const;
191
+ // Returns the string's capacity, i.e. maximum size that the string
192
+ // can grow to without reallocation. Note that for reference counted
193
+ // strings that's technically a lie - even assigning characters
194
+ // within the existing size would cause a reallocation.
195
+ size_t capacity() const;
196
+ // Returns true if the data underlying the string is actually shared
197
+ // across multiple strings (in a refcounted fashion).
198
+ bool isShared() const;
199
+ // Makes sure that at least minCapacity characters are available for
200
+ // the string without reallocation. For reference-counted strings,
201
+ // it should fork the data even if minCapacity < size().
202
+ void reserve(size_t minCapacity);
203
+ };
204
+ */
205
+
206
+ /**
207
+ * This is the core of the string. The code should work on 32- and
208
+ * 64-bit and both big- and little-endianan architectures with any
209
+ * Char size.
210
+ *
211
+ * The storage is selected as follows (assuming we store one-byte
212
+ * characters on a 64-bit machine): (a) "small" strings between 0 and
213
+ * 23 chars are stored in-situ without allocation (the rightmost byte
214
+ * stores the size); (b) "medium" strings from 24 through 254 chars
215
+ * are stored in malloc-allocated memory that is copied eagerly; (c)
216
+ * "large" strings of 255 chars and above are stored in a similar
217
+ * structure as medium arrays, except that the string is
218
+ * reference-counted and copied lazily. the reference count is
219
+ * allocated right before the character array.
220
+ *
221
+ * The discriminator between these three strategies sits in two
222
+ * bits of the rightmost char of the storage:
223
+ * - If neither is set, then the string is small. Its length is represented by
224
+ * the lower-order bits on little-endian or the high-order bits on big-endian
225
+ * of that rightmost character. The value of these six bits is
226
+ * `maxSmallSize - size`, so this quantity must be subtracted from
227
+ * `maxSmallSize` to compute the `size` of the string (see `smallSize()`).
228
+ * This scheme ensures that when `size == `maxSmallSize`, the last byte in the
229
+ * storage is \0. This way, storage will be a null-terminated sequence of
230
+ * bytes, even if all 23 bytes of data are used on a 64-bit architecture.
231
+ * This enables `c_str()` and `data()` to simply return a pointer to the
232
+ * storage.
233
+ *
234
+ * - If the MSb is set, the string is medium width.
235
+ *
236
+ * - If the second MSb is set, then the string is large. On little-endian,
237
+ * these 2 bits are the 2 MSbs of MediumLarge::capacity_, while on
238
+ * big-endian, these 2 bits are the 2 LSbs. This keeps both little-endian
239
+ * and big-endian fbstring_core equivalent with merely different ops used
240
+ * to extract capacity/category.
241
+ */
242
+ template <class Char>
243
+ class fbstring_core {
244
+ public:
245
+ fbstring_core() noexcept { reset(); }
246
+
247
+ fbstring_core(const fbstring_core& rhs) {
248
+ assert(&rhs != this);
249
+ switch (rhs.category()) {
250
+ case Category::isSmall:
251
+ copySmall(rhs);
252
+ break;
253
+ case Category::isMedium:
254
+ copyMedium(rhs);
255
+ break;
256
+ case Category::isLarge:
257
+ copyLarge(rhs);
258
+ break;
259
+ default:
260
+ folly::assume_unreachable();
261
+ }
262
+ assert(size() == rhs.size());
263
+ assert(memcmp(data(), rhs.data(), size() * sizeof(Char)) == 0);
264
+ }
265
+
266
+ fbstring_core& operator=(const fbstring_core& rhs) = delete;
267
+
268
+ fbstring_core(fbstring_core&& goner) noexcept {
269
+ // Take goner's guts
270
+ ml_ = goner.ml_;
271
+ // Clean goner's carcass
272
+ goner.reset();
273
+ }
274
+
275
+ fbstring_core(
276
+ const Char* const data,
277
+ const size_t size,
278
+ bool disableSSO = FBSTRING_DISABLE_SSO) {
279
+ if (!disableSSO && size <= maxSmallSize) {
280
+ initSmall(data, size);
281
+ } else if (size <= maxMediumSize) {
282
+ initMedium(data, size);
283
+ } else {
284
+ initLarge(data, size);
285
+ }
286
+ assert(this->size() == size);
287
+ assert(size == 0 || memcmp(this->data(), data, size * sizeof(Char)) == 0);
288
+ }
289
+
290
+ ~fbstring_core() noexcept {
291
+ if (category() == Category::isSmall) {
292
+ return;
293
+ }
294
+ destroyMediumLarge();
295
+ }
296
+
297
+ // Snatches a previously mallocated string. The parameter "size"
298
+ // is the size of the string, and the parameter "allocatedSize"
299
+ // is the size of the mallocated block. The string must be
300
+ // \0-terminated, so allocatedSize >= size + 1 and data[size] == '\0'.
301
+ //
302
+ // So if you want a 2-character string, pass malloc(3) as "data",
303
+ // pass 2 as "size", and pass 3 as "allocatedSize".
304
+ fbstring_core(
305
+ Char* const data,
306
+ const size_t size,
307
+ const size_t allocatedSize,
308
+ AcquireMallocatedString) {
309
+ if (size > 0) {
310
+ assert(allocatedSize >= size + 1);
311
+ assert(data[size] == '\0');
312
+ // Use the medium string storage
313
+ ml_.data_ = data;
314
+ ml_.size_ = size;
315
+ // Don't forget about null terminator
316
+ ml_.setCapacity(allocatedSize - 1, Category::isMedium);
317
+ } else {
318
+ // No need for the memory
319
+ free(data);
320
+ reset();
321
+ }
322
+ }
323
+
324
+ // swap below doesn't test whether &rhs == this (and instead
325
+ // potentially does extra work) on the premise that the rarity of
326
+ // that situation actually makes the check more expensive than is
327
+ // worth.
328
+ void swap(fbstring_core& rhs) {
329
+ auto const t = ml_;
330
+ ml_ = rhs.ml_;
331
+ rhs.ml_ = t;
332
+ }
333
+
334
+ // In C++11 data() and c_str() are 100% equivalent.
335
+ const Char* data() const { return c_str(); }
336
+
337
+ Char* data() { return c_str(); }
338
+
339
+ Char* mutableData() {
340
+ switch (category()) {
341
+ case Category::isSmall:
342
+ return small_;
343
+ case Category::isMedium:
344
+ return ml_.data_;
345
+ case Category::isLarge:
346
+ return mutableDataLarge();
347
+ }
348
+ folly::assume_unreachable();
349
+ }
350
+
351
+ const Char* c_str() const {
352
+ const Char* ptr = ml_.data_;
353
+ // With this syntax, GCC and Clang generate a CMOV instead of a branch.
354
+ ptr = (category() == Category::isSmall) ? small_ : ptr;
355
+ return ptr;
356
+ }
357
+
358
+ void shrink(const size_t delta) {
359
+ if (category() == Category::isSmall) {
360
+ shrinkSmall(delta);
361
+ } else if (
362
+ category() == Category::isMedium || RefCounted::refs(ml_.data_) == 1) {
363
+ shrinkMedium(delta);
364
+ } else {
365
+ shrinkLarge(delta);
366
+ }
367
+ }
368
+
369
+ FOLLY_NOINLINE
370
+ void reserve(size_t minCapacity, bool disableSSO = FBSTRING_DISABLE_SSO) {
371
+ FOLLY_PUSH_WARNING
372
+ FOLLY_CLANG_DISABLE_WARNING("-Wcovered-switch-default")
373
+ switch (category()) {
374
+ case Category::isSmall:
375
+ reserveSmall(minCapacity, disableSSO);
376
+ break;
377
+ case Category::isMedium:
378
+ reserveMedium(minCapacity);
379
+ break;
380
+ case Category::isLarge:
381
+ reserveLarge(minCapacity);
382
+ break;
383
+ default:
384
+ folly::assume_unreachable();
385
+ }
386
+ FOLLY_POP_WARNING
387
+ assert(capacity() >= minCapacity);
388
+ }
389
+
390
+ Char* expandNoinit(
391
+ const size_t delta,
392
+ bool expGrowth = false,
393
+ bool disableSSO = FBSTRING_DISABLE_SSO);
394
+
395
+ void push_back(Char c) { *expandNoinit(1, /* expGrowth = */ true) = c; }
396
+
397
+ size_t size() const {
398
+ size_t ret = ml_.size_;
399
+ if /* constexpr */ (kIsLittleEndian) {
400
+ // We can save a couple instructions, because the category is
401
+ // small iff the last char, as unsigned, is <= maxSmallSize.
402
+ typedef typename std::make_unsigned<Char>::type UChar;
403
+ auto maybeSmallSize = size_t(maxSmallSize) -
404
+ size_t(static_cast<UChar>(small_[maxSmallSize]));
405
+ // With this syntax, GCC and Clang generate a CMOV instead of a branch.
406
+ ret =
407
+ (static_cast<ptrdiff_t>(maybeSmallSize) >= 0) ? maybeSmallSize : ret;
408
+ } else {
409
+ ret = (category() == Category::isSmall) ? smallSize() : ret;
410
+ }
411
+ return ret;
412
+ }
413
+
414
+ size_t capacity() const {
415
+ FOLLY_PUSH_WARNING
416
+ FOLLY_CLANG_DISABLE_WARNING("-Wcovered-switch-default")
417
+ switch (category()) {
418
+ case Category::isSmall:
419
+ return maxSmallSize;
420
+ case Category::isLarge:
421
+ // For large-sized strings, a multi-referenced chunk has no
422
+ // available capacity. This is because any attempt to append
423
+ // data would trigger a new allocation.
424
+ if (RefCounted::refs(ml_.data_) > 1) {
425
+ return ml_.size_;
426
+ }
427
+ break;
428
+ case Category::isMedium:
429
+ default:
430
+ break;
431
+ }
432
+ FOLLY_POP_WARNING
433
+ return ml_.capacity();
434
+ }
435
+
436
+ bool isShared() const {
437
+ return category() == Category::isLarge && RefCounted::refs(ml_.data_) > 1;
438
+ }
439
+
440
+ private:
441
+ Char* c_str() {
442
+ Char* ptr = ml_.data_;
443
+ // With this syntax, GCC and Clang generate a CMOV instead of a branch.
444
+ ptr = (category() == Category::isSmall) ? small_ : ptr;
445
+ return ptr;
446
+ }
447
+
448
+ void reset() { setSmallSize(0); }
449
+
450
+ FOLLY_NOINLINE void destroyMediumLarge() noexcept {
451
+ auto const c = category();
452
+ assert(c != Category::isSmall);
453
+ if (c == Category::isMedium) {
454
+ free(ml_.data_);
455
+ } else {
456
+ RefCounted::decrementRefs(ml_.data_);
457
+ }
458
+ }
459
+
460
+ struct RefCounted {
461
+ std::atomic<size_t> refCount_;
462
+ Char data_[1];
463
+
464
+ constexpr static size_t getDataOffset() {
465
+ return offsetof(RefCounted, data_);
466
+ }
467
+
468
+ static RefCounted* fromData(Char* p) {
469
+ return static_cast<RefCounted*>(static_cast<void*>(
470
+ static_cast<unsigned char*>(static_cast<void*>(p)) -
471
+ getDataOffset()));
472
+ }
473
+
474
+ static size_t refs(Char* p) {
475
+ return fromData(p)->refCount_.load(std::memory_order_acquire);
476
+ }
477
+
478
+ static void incrementRefs(Char* p) {
479
+ fromData(p)->refCount_.fetch_add(1, std::memory_order_acq_rel);
480
+ }
481
+
482
+ static void decrementRefs(Char* p) {
483
+ auto const dis = fromData(p);
484
+ size_t oldcnt = dis->refCount_.fetch_sub(1, std::memory_order_acq_rel);
485
+ assert(oldcnt > 0);
486
+ if (oldcnt == 1) {
487
+ ::free(dis);
488
+ }
489
+ }
490
+
491
+ static RefCounted* create(size_t* size) {
492
+ size_t capacityBytes;
493
+ if (!folly::checked_add(&capacityBytes, *size, size_t(1))) {
494
+ throw_exception(std::length_error(""));
495
+ }
496
+ if (!folly::checked_muladd(
497
+ &capacityBytes, capacityBytes, sizeof(Char), getDataOffset())) {
498
+ throw_exception(std::length_error(""));
499
+ }
500
+ const size_t allocSize = goodMallocSize(capacityBytes);
501
+ auto result = static_cast<RefCounted*>(checkedMalloc(allocSize));
502
+ result->refCount_.store(1, std::memory_order_release);
503
+ *size = (allocSize - getDataOffset()) / sizeof(Char) - 1;
504
+ return result;
505
+ }
506
+
507
+ static RefCounted* create(const Char* data, size_t* size) {
508
+ const size_t effectiveSize = *size;
509
+ auto result = create(size);
510
+ if (FOLLY_LIKELY(effectiveSize > 0)) {
511
+ fbstring_detail::podCopy(data, data + effectiveSize, result->data_);
512
+ }
513
+ return result;
514
+ }
515
+
516
+ static RefCounted* reallocate(
517
+ Char* const data,
518
+ const size_t currentSize,
519
+ const size_t currentCapacity,
520
+ size_t* newCapacity) {
521
+ assert(*newCapacity > 0 && *newCapacity > currentSize);
522
+ size_t capacityBytes;
523
+ if (!folly::checked_add(&capacityBytes, *newCapacity, size_t(1))) {
524
+ throw_exception(std::length_error(""));
525
+ }
526
+ if (!folly::checked_muladd(
527
+ &capacityBytes, capacityBytes, sizeof(Char), getDataOffset())) {
528
+ throw_exception(std::length_error(""));
529
+ }
530
+ const size_t allocNewCapacity = goodMallocSize(capacityBytes);
531
+ auto const dis = fromData(data);
532
+ assert(dis->refCount_.load(std::memory_order_acquire) == 1);
533
+ auto result = static_cast<RefCounted*>(smartRealloc(
534
+ dis,
535
+ getDataOffset() + (currentSize + 1) * sizeof(Char),
536
+ getDataOffset() + (currentCapacity + 1) * sizeof(Char),
537
+ allocNewCapacity));
538
+ assert(result->refCount_.load(std::memory_order_acquire) == 1);
539
+ *newCapacity = (allocNewCapacity - getDataOffset()) / sizeof(Char) - 1;
540
+ return result;
541
+ }
542
+ };
543
+
544
+ typedef uint8_t category_type;
545
+
546
+ enum class Category : category_type {
547
+ isSmall = 0,
548
+ isMedium = kIsLittleEndian ? 0x80 : 0x2,
549
+ isLarge = kIsLittleEndian ? 0x40 : 0x1,
550
+ };
551
+
552
+ Category category() const {
553
+ // works for both big-endian and little-endian
554
+ return static_cast<Category>(bytes_[lastChar] & categoryExtractMask);
555
+ }
556
+
557
+ struct MediumLarge {
558
+ Char* data_;
559
+ size_t size_;
560
+ size_t capacity_;
561
+
562
+ size_t capacity() const {
563
+ return kIsLittleEndian ? capacity_ & capacityExtractMask : capacity_ >> 2;
564
+ }
565
+
566
+ void setCapacity(size_t cap, Category cat) {
567
+ capacity_ = kIsLittleEndian
568
+ ? cap | (static_cast<size_t>(cat) << kCategoryShift)
569
+ : (cap << 2) | static_cast<size_t>(cat);
570
+ }
571
+ };
572
+
573
+ union {
574
+ uint8_t bytes_[sizeof(MediumLarge)]; // For accessing the last byte.
575
+ Char small_[sizeof(MediumLarge) / sizeof(Char)];
576
+ MediumLarge ml_;
577
+ };
578
+
579
+ constexpr static size_t lastChar = sizeof(MediumLarge) - 1;
580
+ constexpr static size_t maxSmallSize = lastChar / sizeof(Char);
581
+ constexpr static size_t maxMediumSize = 254 / sizeof(Char);
582
+ constexpr static uint8_t categoryExtractMask = kIsLittleEndian ? 0xC0 : 0x3;
583
+ constexpr static size_t kCategoryShift = (sizeof(size_t) - 1) * 8;
584
+ constexpr static size_t capacityExtractMask = kIsLittleEndian
585
+ ? ~(size_t(categoryExtractMask) << kCategoryShift)
586
+ : 0x0 /* unused */;
587
+
588
+ static_assert(
589
+ !(sizeof(MediumLarge) % sizeof(Char)),
590
+ "Corrupt memory layout for fbstring.");
591
+
592
+ size_t smallSize() const {
593
+ assert(category() == Category::isSmall);
594
+ constexpr auto shift = kIsLittleEndian ? 0 : 2;
595
+ auto smallShifted = static_cast<size_t>(small_[maxSmallSize]) >> shift;
596
+ assert(static_cast<size_t>(maxSmallSize) >= smallShifted);
597
+ return static_cast<size_t>(maxSmallSize) - smallShifted;
598
+ }
599
+
600
+ void setSmallSize(size_t s) {
601
+ // Warning: this should work with uninitialized strings too,
602
+ // so don't assume anything about the previous value of
603
+ // small_[maxSmallSize].
604
+ assert(s <= maxSmallSize);
605
+ constexpr auto shift = kIsLittleEndian ? 0 : 2;
606
+ small_[maxSmallSize] = char((maxSmallSize - s) << shift);
607
+ small_[s] = '\0';
608
+ assert(category() == Category::isSmall && size() == s);
609
+ }
610
+
611
+ void copySmall(const fbstring_core&);
612
+ void copyMedium(const fbstring_core&);
613
+ void copyLarge(const fbstring_core&);
614
+
615
+ void initSmall(const Char* data, size_t size);
616
+ void initMedium(const Char* data, size_t size);
617
+ void initLarge(const Char* data, size_t size);
618
+
619
+ void reserveSmall(size_t minCapacity, bool disableSSO);
620
+ void reserveMedium(size_t minCapacity);
621
+ void reserveLarge(size_t minCapacity);
622
+
623
+ void shrinkSmall(size_t delta);
624
+ void shrinkMedium(size_t delta);
625
+ void shrinkLarge(size_t delta);
626
+
627
+ void unshare(size_t minCapacity = 0);
628
+ Char* mutableDataLarge();
629
+ };
630
+
631
+ template <class Char>
632
+ inline void fbstring_core<Char>::copySmall(const fbstring_core& rhs) {
633
+ static_assert(offsetof(MediumLarge, data_) == 0, "fbstring layout failure");
634
+ static_assert(
635
+ offsetof(MediumLarge, size_) == sizeof(ml_.data_),
636
+ "fbstring layout failure");
637
+ static_assert(
638
+ offsetof(MediumLarge, capacity_) == 2 * sizeof(ml_.data_),
639
+ "fbstring layout failure");
640
+ // Just write the whole thing, don't look at details. In
641
+ // particular we need to copy capacity anyway because we want
642
+ // to set the size (don't forget that the last character,
643
+ // which stores a short string's length, is shared with the
644
+ // ml_.capacity field).
645
+ ml_ = rhs.ml_;
646
+ assert(category() == Category::isSmall && this->size() == rhs.size());
647
+ }
648
+
649
+ template <class Char>
650
+ FOLLY_NOINLINE void fbstring_core<Char>::copyMedium(const fbstring_core& rhs) {
651
+ // Medium strings are copied eagerly. Don't forget to allocate
652
+ // one extra Char for the null terminator.
653
+ auto const allocSize = goodMallocSize((1 + rhs.ml_.size_) * sizeof(Char));
654
+ ml_.data_ = static_cast<Char*>(checkedMalloc(allocSize));
655
+ // Also copies terminator.
656
+ fbstring_detail::podCopy(
657
+ rhs.ml_.data_, rhs.ml_.data_ + rhs.ml_.size_ + 1, ml_.data_);
658
+ ml_.size_ = rhs.ml_.size_;
659
+ ml_.setCapacity(allocSize / sizeof(Char) - 1, Category::isMedium);
660
+ assert(category() == Category::isMedium);
661
+ }
662
+
663
+ template <class Char>
664
+ FOLLY_NOINLINE void fbstring_core<Char>::copyLarge(const fbstring_core& rhs) {
665
+ // Large strings are just refcounted
666
+ ml_ = rhs.ml_;
667
+ RefCounted::incrementRefs(ml_.data_);
668
+ assert(category() == Category::isLarge && size() == rhs.size());
669
+ }
670
+
671
+ // Small strings are bitblitted
672
+ template <class Char>
673
+ inline void fbstring_core<Char>::initSmall(
674
+ const Char* const data, const size_t size) {
675
+ // Layout is: Char* data_, size_t size_, size_t capacity_
676
+ static_assert(
677
+ sizeof(*this) == sizeof(Char*) + 2 * sizeof(size_t),
678
+ "fbstring has unexpected size");
679
+ static_assert(
680
+ sizeof(Char*) == sizeof(size_t), "fbstring size assumption violation");
681
+ // sizeof(size_t) must be a power of 2
682
+ static_assert(
683
+ (sizeof(size_t) & (sizeof(size_t) - 1)) == 0,
684
+ "fbstring size assumption violation");
685
+
686
+ // If data is aligned, use fast word-wise copying. Otherwise,
687
+ // use conservative memcpy.
688
+ // The word-wise path reads bytes which are outside the range of
689
+ // the string, and makes ASan unhappy, so we disable it when
690
+ // compiling with ASan.
691
+ #ifndef FOLLY_SANITIZE_ADDRESS
692
+ if ((reinterpret_cast<size_t>(data) & (sizeof(size_t) - 1)) == 0) {
693
+ const size_t byteSize = size * sizeof(Char);
694
+ constexpr size_t wordWidth = sizeof(size_t);
695
+ switch ((byteSize + wordWidth - 1) / wordWidth) { // Number of words.
696
+ case 3:
697
+ ml_.capacity_ = reinterpret_cast<const size_t*>(data)[2];
698
+ [[fallthrough]];
699
+ case 2:
700
+ ml_.size_ = reinterpret_cast<const size_t*>(data)[1];
701
+ [[fallthrough]];
702
+ case 1:
703
+ ml_.data_ = *reinterpret_cast<Char**>(const_cast<Char*>(data));
704
+ [[fallthrough]];
705
+ case 0:
706
+ break;
707
+ }
708
+ } else
709
+ #endif
710
+ {
711
+ if (size != 0) {
712
+ fbstring_detail::podCopy(data, data + size, small_);
713
+ }
714
+ }
715
+ setSmallSize(size);
716
+ }
717
+
718
+ template <class Char>
719
+ FOLLY_NOINLINE void fbstring_core<Char>::initMedium(
720
+ const Char* const data, const size_t size) {
721
+ // Medium strings are allocated normally. Don't forget to
722
+ // allocate one extra Char for the terminating null.
723
+ auto const allocSize = goodMallocSize((1 + size) * sizeof(Char));
724
+ ml_.data_ = static_cast<Char*>(checkedMalloc(allocSize));
725
+ if (FOLLY_LIKELY(size > 0)) {
726
+ fbstring_detail::podCopy(data, data + size, ml_.data_);
727
+ }
728
+ ml_.size_ = size;
729
+ ml_.setCapacity(allocSize / sizeof(Char) - 1, Category::isMedium);
730
+ ml_.data_[size] = '\0';
731
+ }
732
+
733
+ template <class Char>
734
+ FOLLY_NOINLINE void fbstring_core<Char>::initLarge(
735
+ const Char* const data, const size_t size) {
736
+ // Large strings are allocated differently
737
+ size_t effectiveCapacity = size;
738
+ auto const newRC = RefCounted::create(data, &effectiveCapacity);
739
+ ml_.data_ = newRC->data_;
740
+ ml_.size_ = size;
741
+ ml_.setCapacity(effectiveCapacity, Category::isLarge);
742
+ ml_.data_[size] = '\0';
743
+ }
744
+
745
+ template <class Char>
746
+ FOLLY_NOINLINE void fbstring_core<Char>::unshare(size_t minCapacity) {
747
+ assert(category() == Category::isLarge);
748
+ size_t effectiveCapacity = std::max(minCapacity, ml_.capacity());
749
+ auto const newRC = RefCounted::create(&effectiveCapacity);
750
+ // If this fails, someone placed the wrong capacity in an
751
+ // fbstring.
752
+ assert(effectiveCapacity >= ml_.capacity());
753
+ // Also copies terminator.
754
+ fbstring_detail::podCopy(ml_.data_, ml_.data_ + ml_.size_ + 1, newRC->data_);
755
+ RefCounted::decrementRefs(ml_.data_);
756
+ ml_.data_ = newRC->data_;
757
+ ml_.setCapacity(effectiveCapacity, Category::isLarge);
758
+ // size_ remains unchanged.
759
+ }
760
+
761
+ template <class Char>
762
+ inline Char* fbstring_core<Char>::mutableDataLarge() {
763
+ assert(category() == Category::isLarge);
764
+ if (RefCounted::refs(ml_.data_) > 1) { // Ensure unique.
765
+ unshare();
766
+ }
767
+ return ml_.data_;
768
+ }
769
+
770
+ template <class Char>
771
+ FOLLY_NOINLINE void fbstring_core<Char>::reserveLarge(size_t minCapacity) {
772
+ assert(category() == Category::isLarge);
773
+ if (RefCounted::refs(ml_.data_) > 1) { // Ensure unique
774
+ // We must make it unique regardless; in-place reallocation is
775
+ // useless if the string is shared. In order to not surprise
776
+ // people, reserve the new block at current capacity or
777
+ // more. That way, a string's capacity never shrinks after a
778
+ // call to reserve.
779
+ unshare(minCapacity);
780
+ } else {
781
+ // String is not shared, so let's try to realloc (if needed)
782
+ if (minCapacity > ml_.capacity()) {
783
+ // Asking for more memory
784
+ auto const newRC = RefCounted::reallocate(
785
+ ml_.data_, ml_.size_, ml_.capacity(), &minCapacity);
786
+ ml_.data_ = newRC->data_;
787
+ ml_.setCapacity(minCapacity, Category::isLarge);
788
+ }
789
+ assert(capacity() >= minCapacity);
790
+ }
791
+ }
792
+
793
+ template <class Char>
794
+ FOLLY_NOINLINE void fbstring_core<Char>::reserveMedium(
795
+ const size_t minCapacity) {
796
+ assert(category() == Category::isMedium);
797
+ // String is not shared
798
+ if (minCapacity <= ml_.capacity()) {
799
+ return; // nothing to do, there's enough room
800
+ }
801
+ if (minCapacity <= maxMediumSize) {
802
+ // Keep the string at medium size. Don't forget to allocate
803
+ // one extra Char for the terminating null.
804
+ size_t capacityBytes = goodMallocSize((1 + minCapacity) * sizeof(Char));
805
+ // Also copies terminator.
806
+ ml_.data_ = static_cast<Char*>(smartRealloc(
807
+ ml_.data_,
808
+ (ml_.size_ + 1) * sizeof(Char),
809
+ (ml_.capacity() + 1) * sizeof(Char),
810
+ capacityBytes));
811
+ ml_.setCapacity(capacityBytes / sizeof(Char) - 1, Category::isMedium);
812
+ } else {
813
+ // Conversion from medium to large string
814
+ fbstring_core nascent;
815
+ // Will recurse to another branch of this function
816
+ nascent.reserve(minCapacity);
817
+ nascent.ml_.size_ = ml_.size_;
818
+ // Also copies terminator.
819
+ fbstring_detail::podCopy(
820
+ ml_.data_, ml_.data_ + ml_.size_ + 1, nascent.ml_.data_);
821
+ nascent.swap(*this);
822
+ assert(capacity() >= minCapacity);
823
+ }
824
+ }
825
+
826
+ template <class Char>
827
+ FOLLY_NOINLINE void fbstring_core<Char>::reserveSmall(
828
+ size_t minCapacity, const bool disableSSO) {
829
+ assert(category() == Category::isSmall);
830
+ if (!disableSSO && minCapacity <= maxSmallSize) {
831
+ // small
832
+ // Nothing to do, everything stays put
833
+ } else if (minCapacity <= maxMediumSize) {
834
+ // medium
835
+ // Don't forget to allocate one extra Char for the terminating null
836
+ auto const allocSizeBytes =
837
+ goodMallocSize((1 + minCapacity) * sizeof(Char));
838
+ auto const pData = static_cast<Char*>(checkedMalloc(allocSizeBytes));
839
+ auto const size = smallSize();
840
+ // Also copies terminator.
841
+ fbstring_detail::podCopy(small_, small_ + size + 1, pData);
842
+ ml_.data_ = pData;
843
+ ml_.size_ = size;
844
+ ml_.setCapacity(allocSizeBytes / sizeof(Char) - 1, Category::isMedium);
845
+ } else {
846
+ // large
847
+ auto const newRC = RefCounted::create(&minCapacity);
848
+ auto const size = smallSize();
849
+ // Also copies terminator.
850
+ fbstring_detail::podCopy(small_, small_ + size + 1, newRC->data_);
851
+ ml_.data_ = newRC->data_;
852
+ ml_.size_ = size;
853
+ ml_.setCapacity(minCapacity, Category::isLarge);
854
+ assert(capacity() >= minCapacity);
855
+ }
856
+ }
857
+
858
+ template <class Char>
859
+ inline Char* fbstring_core<Char>::expandNoinit(
860
+ const size_t delta,
861
+ bool expGrowth, /* = false */
862
+ bool disableSSO /* = FBSTRING_DISABLE_SSO */) {
863
+ // Strategy is simple: make room, then change size
864
+ assert(capacity() >= size());
865
+ size_t sz, newSz;
866
+ if (category() == Category::isSmall) {
867
+ sz = smallSize();
868
+ newSz = sz + delta;
869
+ if (!disableSSO && FOLLY_LIKELY(newSz <= maxSmallSize)) {
870
+ setSmallSize(newSz);
871
+ return small_ + sz;
872
+ }
873
+ reserveSmall(
874
+ expGrowth ? std::max(newSz, 2 * maxSmallSize) : newSz, disableSSO);
875
+ } else {
876
+ sz = ml_.size_;
877
+ newSz = sz + delta;
878
+ if (FOLLY_UNLIKELY(newSz > capacity())) {
879
+ // ensures not shared
880
+ reserve(expGrowth ? std::max(newSz, 1 + capacity() * 3 / 2) : newSz);
881
+ }
882
+ }
883
+ assert(capacity() >= newSz);
884
+ // Category can't be small - we took care of that above
885
+ assert(category() == Category::isMedium || category() == Category::isLarge);
886
+ ml_.size_ = newSz;
887
+ ml_.data_[newSz] = '\0';
888
+ assert(size() == newSz);
889
+ return ml_.data_ + sz;
890
+ }
891
+
892
+ template <class Char>
893
+ inline void fbstring_core<Char>::shrinkSmall(const size_t delta) {
894
+ // Check for underflow
895
+ assert(delta <= smallSize());
896
+ setSmallSize(smallSize() - delta);
897
+ }
898
+
899
+ template <class Char>
900
+ inline void fbstring_core<Char>::shrinkMedium(const size_t delta) {
901
+ // Medium strings and unique large strings need no special
902
+ // handling.
903
+ assert(ml_.size_ >= delta);
904
+ ml_.size_ -= delta;
905
+ ml_.data_[ml_.size_] = '\0';
906
+ }
907
+
908
+ template <class Char>
909
+ inline void fbstring_core<Char>::shrinkLarge(const size_t delta) {
910
+ assert(ml_.size_ >= delta);
911
+ // Shared large string, must make unique. This is because of the
912
+ // durn terminator must be written, which may trample the shared
913
+ // data.
914
+ if (delta) {
915
+ fbstring_core(ml_.data_, ml_.size_ - delta).swap(*this);
916
+ }
917
+ // No need to write the terminator.
918
+ }
919
+
920
+ /**
921
+ * Dummy fbstring core that uses an actual std::string. This doesn't
922
+ * make any sense - it's just for testing purposes.
923
+ */
924
+ template <class Char>
925
+ class dummy_fbstring_core {
926
+ public:
927
+ dummy_fbstring_core() {}
928
+ dummy_fbstring_core(const dummy_fbstring_core& another)
929
+ : backend_(another.backend_) {}
930
+ dummy_fbstring_core(const Char* s, size_t n) : backend_(s, n) {}
931
+ void swap(dummy_fbstring_core& rhs) { backend_.swap(rhs.backend_); }
932
+ const Char* data() const { return backend_.data(); }
933
+ Char* mutableData() { return const_cast<Char*>(backend_.data()); }
934
+ void shrink(size_t delta) {
935
+ assert(delta <= size());
936
+ backend_.resize(size() - delta);
937
+ }
938
+ Char* expandNoinit(size_t delta) {
939
+ auto const sz = size();
940
+ backend_.resize(size() + delta);
941
+ return backend_.data() + sz;
942
+ }
943
+ void push_back(Char c) { backend_.push_back(c); }
944
+ size_t size() const { return backend_.size(); }
945
+ size_t capacity() const { return backend_.capacity(); }
946
+ bool isShared() const { return false; }
947
+ void reserve(size_t minCapacity) { backend_.reserve(minCapacity); }
948
+
949
+ private:
950
+ std::basic_string<Char> backend_;
951
+ };
952
+
953
+ /**
954
+ * This is the basic_string replacement. For conformity,
955
+ * basic_fbstring takes the same template parameters, plus the last
956
+ * one which is the core.
957
+ */
958
+ template <
959
+ typename E,
960
+ class T = std::char_traits<E>,
961
+ class A = std::allocator<E>,
962
+ class Storage = fbstring_core<E>>
963
+ class basic_fbstring {
964
+ static_assert(
965
+ std::is_same<A, std::allocator<E>>::value,
966
+ "fbstring ignores custom allocators");
967
+
968
+ template <typename Ex, typename... Args>
969
+ FOLLY_ALWAYS_INLINE static void enforce(bool condition, Args&&... args) {
970
+ if (!condition) {
971
+ throw_exception<Ex>(static_cast<Args&&>(args)...);
972
+ }
973
+ }
974
+
975
+ bool isSane() const {
976
+ return begin() <= end() && empty() == (size() == 0) &&
977
+ empty() == (begin() == end()) && size() <= max_size() &&
978
+ capacity() <= max_size() && size() <= capacity() &&
979
+ begin()[size()] == '\0';
980
+ }
981
+
982
+ struct Invariant {
983
+ Invariant& operator=(const Invariant&) = delete;
984
+ explicit Invariant(const basic_fbstring& s) noexcept : s_(s) {
985
+ assert(s_.isSane());
986
+ }
987
+ ~Invariant() noexcept { assert(s_.isSane()); }
988
+
989
+ private:
990
+ const basic_fbstring& s_;
991
+ };
992
+
993
+ public:
994
+ // types
995
+ typedef T traits_type;
996
+ typedef typename traits_type::char_type value_type;
997
+ typedef A allocator_type;
998
+ typedef typename std::allocator_traits<A>::size_type size_type;
999
+ typedef typename std::allocator_traits<A>::difference_type difference_type;
1000
+
1001
+ typedef typename std::allocator_traits<A>::value_type& reference;
1002
+ typedef typename std::allocator_traits<A>::value_type const& const_reference;
1003
+ typedef typename std::allocator_traits<A>::pointer pointer;
1004
+ typedef typename std::allocator_traits<A>::const_pointer const_pointer;
1005
+
1006
+ typedef E* iterator;
1007
+ typedef const E* const_iterator;
1008
+ typedef std::reverse_iterator<iterator> reverse_iterator;
1009
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1010
+
1011
+ static constexpr size_type npos = size_type(-1);
1012
+ typedef std::true_type IsRelocatable;
1013
+
1014
+ private:
1015
+ using string_view_type = std::basic_string_view<value_type, traits_type>;
1016
+
1017
+ template <typename StringViewLike>
1018
+ static inline constexpr bool is_string_view_like_v =
1019
+ std::is_convertible_v<StringViewLike const&, string_view_type> &&
1020
+ !std::is_convertible_v<StringViewLike const&, const_pointer>;
1021
+
1022
+ template <typename StringViewLike, typename Dummy>
1023
+ using if_is_string_view_like_t =
1024
+ std::enable_if_t<is_string_view_like_v<StringViewLike>, Dummy>;
1025
+
1026
+ static void procrustes(size_type& n, size_type nmax) {
1027
+ if (n > nmax) {
1028
+ n = nmax;
1029
+ }
1030
+ }
1031
+
1032
+ static size_type traitsLength(const value_type* s);
1033
+
1034
+ struct string_view_ctor {};
1035
+ FOLLY_NOINLINE basic_fbstring(
1036
+ string_view_type view, const A&, string_view_ctor)
1037
+ : store_(view.data(), view.size()) {}
1038
+
1039
+ public:
1040
+ // C++11 21.4.2 construct/copy/destroy
1041
+
1042
+ // Note: while the following two constructors can be (and previously were)
1043
+ // collapsed into one constructor written this way:
1044
+ //
1045
+ // explicit basic_fbstring(const A& a = A()) noexcept { }
1046
+ //
1047
+ // This can cause Clang (at least version 3.7) to fail with the error:
1048
+ // "chosen constructor is explicit in copy-initialization ...
1049
+ // in implicit initialization of field '(x)' with omitted initializer"
1050
+ //
1051
+ // if used in a struct which is default-initialized. Hence the split into
1052
+ // these two separate constructors.
1053
+
1054
+ basic_fbstring() noexcept : basic_fbstring(A()) {}
1055
+ /* implicit */ basic_fbstring(std::nullptr_t) = delete;
1056
+
1057
+ explicit basic_fbstring(const A&) noexcept {}
1058
+
1059
+ basic_fbstring(const basic_fbstring& str) : store_(str.store_) {}
1060
+
1061
+ // Move constructor
1062
+ basic_fbstring(basic_fbstring&& goner) noexcept
1063
+ : store_(std::move(goner.store_)) {}
1064
+
1065
+ // This is defined for compatibility with std::string
1066
+ template <typename A2>
1067
+ /* implicit */ basic_fbstring(const std::basic_string<E, T, A2>& str)
1068
+ : store_(str.data(), str.size()) {}
1069
+
1070
+ basic_fbstring(
1071
+ const basic_fbstring& str,
1072
+ size_type pos,
1073
+ size_type n = npos,
1074
+ const A& /* a */ = A()) {
1075
+ assign(str, pos, n);
1076
+ }
1077
+
1078
+ FOLLY_NOINLINE
1079
+ /* implicit */ basic_fbstring(const value_type* s, const A& /*a*/ = A())
1080
+ : store_(s, traitsLength(s)) {}
1081
+
1082
+ FOLLY_NOINLINE
1083
+ basic_fbstring(const value_type* s, size_type n, const A& /*a*/ = A())
1084
+ : store_(s, n) {}
1085
+
1086
+ FOLLY_NOINLINE
1087
+ basic_fbstring(size_type n, value_type c, const A& /*a*/ = A()) {
1088
+ auto const pData = store_.expandNoinit(n);
1089
+ fbstring_detail::podFill(pData, pData + n, c);
1090
+ }
1091
+
1092
+ template <class InIt>
1093
+ FOLLY_NOINLINE basic_fbstring(
1094
+ InIt begin,
1095
+ InIt end,
1096
+ typename std::enable_if<
1097
+ !std::is_same<InIt, value_type*>::value,
1098
+ const A>::type& /*a*/
1099
+ = A()) {
1100
+ assign(begin, end);
1101
+ }
1102
+
1103
+ // Specialization for const char*, const char*
1104
+ FOLLY_NOINLINE
1105
+ basic_fbstring(const value_type* b, const value_type* e, const A& /*a*/ = A())
1106
+ : store_(b, size_type(e - b)) {}
1107
+
1108
+ // Nonstandard constructor
1109
+ basic_fbstring(
1110
+ value_type* s, size_type n, size_type c, AcquireMallocatedString a)
1111
+ : store_(s, n, c, a) {}
1112
+
1113
+ // Construction from initialization list
1114
+ FOLLY_NOINLINE
1115
+ basic_fbstring(std::initializer_list<value_type> il) {
1116
+ assign(il.begin(), il.end());
1117
+ }
1118
+
1119
+ template <
1120
+ typename StringViewLike,
1121
+ if_is_string_view_like_t<StringViewLike, int> = 0>
1122
+ explicit basic_fbstring(const StringViewLike& view, const A& a = A())
1123
+ : basic_fbstring(string_view_type(view), a, string_view_ctor{}) {}
1124
+
1125
+ template <
1126
+ typename StringViewLike,
1127
+ if_is_string_view_like_t<StringViewLike, int> = 0>
1128
+ basic_fbstring(
1129
+ const StringViewLike& view, size_type pos, size_type n, const A& a = A())
1130
+ : basic_fbstring(
1131
+ string_view_type(view).substr(pos, n), a, string_view_ctor{}) {}
1132
+
1133
+ ~basic_fbstring() noexcept {}
1134
+
1135
+ basic_fbstring& operator=(const basic_fbstring& lhs);
1136
+
1137
+ // Move assignment
1138
+ basic_fbstring& operator=(basic_fbstring&& goner) noexcept;
1139
+
1140
+ // Compatibility with std::string
1141
+ template <typename A2>
1142
+ basic_fbstring& operator=(const std::basic_string<E, T, A2>& rhs) {
1143
+ return assign(rhs.data(), rhs.size());
1144
+ }
1145
+
1146
+ // Compatibility with std::string
1147
+ std::basic_string<E, T, A> toStdString() const {
1148
+ return std::basic_string<E, T, A>(data(), size());
1149
+ }
1150
+
1151
+ basic_fbstring& operator=(std::nullptr_t) = delete;
1152
+
1153
+ basic_fbstring& operator=(const value_type* s) { return assign(s); }
1154
+
1155
+ basic_fbstring& operator=(value_type c);
1156
+
1157
+ // This actually goes directly against the C++ spec, but the
1158
+ // value_type overload is dangerous, so we're explicitly deleting
1159
+ // any overloads of operator= that could implicitly convert to
1160
+ // value_type.
1161
+ // Note that we do need to explicitly specify the template types because
1162
+ // otherwise MSVC 2017 will aggressively pre-resolve value_type to
1163
+ // traits_type::char_type, which won't compare as equal when determining
1164
+ // which overload the implementation is referring to.
1165
+ template <typename TP>
1166
+ typename std::enable_if<
1167
+ std::is_convertible<
1168
+ TP,
1169
+ typename basic_fbstring<E, T, A, Storage>::value_type>::value &&
1170
+ !std::is_same<
1171
+ typename std::decay<TP>::type,
1172
+ typename basic_fbstring<E, T, A, Storage>::value_type>::value,
1173
+ basic_fbstring<E, T, A, Storage>&>::type
1174
+ operator=(TP c) = delete;
1175
+
1176
+ basic_fbstring& operator=(std::initializer_list<value_type> il) {
1177
+ return assign(il.begin(), il.end());
1178
+ }
1179
+
1180
+ operator string_view_type() const noexcept { return {data(), size()}; }
1181
+
1182
+ // C++11 21.4.3 iterators:
1183
+ iterator begin() { return store_.mutableData(); }
1184
+
1185
+ const_iterator begin() const { return store_.data(); }
1186
+
1187
+ const_iterator cbegin() const { return begin(); }
1188
+
1189
+ iterator end() { return store_.mutableData() + store_.size(); }
1190
+
1191
+ const_iterator end() const { return store_.data() + store_.size(); }
1192
+
1193
+ const_iterator cend() const { return end(); }
1194
+
1195
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
1196
+
1197
+ const_reverse_iterator rbegin() const {
1198
+ return const_reverse_iterator(end());
1199
+ }
1200
+
1201
+ const_reverse_iterator crbegin() const { return rbegin(); }
1202
+
1203
+ reverse_iterator rend() { return reverse_iterator(begin()); }
1204
+
1205
+ const_reverse_iterator rend() const {
1206
+ return const_reverse_iterator(begin());
1207
+ }
1208
+
1209
+ const_reverse_iterator crend() const { return rend(); }
1210
+
1211
+ // Added by C++11
1212
+ // C++11 21.4.5, element access:
1213
+ const value_type& front() const { return *begin(); }
1214
+ const value_type& back() const {
1215
+ assert(!empty());
1216
+ // Should be begin()[size() - 1], but that branches twice
1217
+ return *(end() - 1);
1218
+ }
1219
+ value_type& front() { return *begin(); }
1220
+ value_type& back() {
1221
+ assert(!empty());
1222
+ // Should be begin()[size() - 1], but that branches twice
1223
+ return *(end() - 1);
1224
+ }
1225
+ void pop_back() {
1226
+ assert(!empty());
1227
+ store_.shrink(1);
1228
+ }
1229
+
1230
+ // C++11 21.4.4 capacity:
1231
+ size_type size() const { return store_.size(); }
1232
+
1233
+ size_type length() const { return size(); }
1234
+
1235
+ size_type max_size() const { return std::numeric_limits<size_type>::max(); }
1236
+
1237
+ void resize(size_type n, value_type c = value_type());
1238
+
1239
+ size_type capacity() const { return store_.capacity(); }
1240
+
1241
+ void reserve(size_type res_arg = 0) {
1242
+ enforce<std::length_error>(res_arg <= max_size(), "");
1243
+ store_.reserve(res_arg);
1244
+ }
1245
+
1246
+ void shrink_to_fit() {
1247
+ // Shrink only if slack memory is sufficiently large
1248
+ if (capacity() < size() * 3 / 2) {
1249
+ return;
1250
+ }
1251
+ basic_fbstring(cbegin(), cend()).swap(*this);
1252
+ }
1253
+
1254
+ void clear() { resize(0); }
1255
+
1256
+ bool empty() const { return size() == 0; }
1257
+
1258
+ // C++11 21.4.5 element access:
1259
+ const_reference operator[](size_type pos) const { return *(begin() + pos); }
1260
+
1261
+ reference operator[](size_type pos) { return *(begin() + pos); }
1262
+
1263
+ const_reference at(size_type n) const {
1264
+ enforce<std::out_of_range>(n < size(), "");
1265
+ return (*this)[n];
1266
+ }
1267
+
1268
+ reference at(size_type n) {
1269
+ enforce<std::out_of_range>(n < size(), "");
1270
+ return (*this)[n];
1271
+ }
1272
+
1273
+ // C++11 21.4.6 modifiers:
1274
+ basic_fbstring& operator+=(const basic_fbstring& str) { return append(str); }
1275
+
1276
+ basic_fbstring& operator+=(const value_type* s) { return append(s); }
1277
+
1278
+ basic_fbstring& operator+=(const value_type c) {
1279
+ push_back(c);
1280
+ return *this;
1281
+ }
1282
+
1283
+ basic_fbstring& operator+=(std::initializer_list<value_type> il) {
1284
+ append(il);
1285
+ return *this;
1286
+ }
1287
+
1288
+ template <
1289
+ typename StringViewLike,
1290
+ if_is_string_view_like_t<StringViewLike, int> = 0>
1291
+ basic_fbstring& operator+=(const StringViewLike& like) {
1292
+ append(like);
1293
+ return *this;
1294
+ }
1295
+
1296
+ basic_fbstring& append(const basic_fbstring& str);
1297
+
1298
+ basic_fbstring& append(
1299
+ const basic_fbstring& str, const size_type pos, size_type n);
1300
+
1301
+ basic_fbstring& append(const value_type* s, size_type n);
1302
+
1303
+ basic_fbstring& append(const value_type* s) {
1304
+ return append(s, traitsLength(s));
1305
+ }
1306
+
1307
+ basic_fbstring& append(size_type n, value_type c);
1308
+
1309
+ template <class InputIterator>
1310
+ basic_fbstring& append(InputIterator first, InputIterator last) {
1311
+ insert(end(), first, last);
1312
+ return *this;
1313
+ }
1314
+
1315
+ basic_fbstring& append(std::initializer_list<value_type> il) {
1316
+ return append(il.begin(), il.end());
1317
+ }
1318
+
1319
+ template <
1320
+ typename StringViewLike,
1321
+ if_is_string_view_like_t<StringViewLike, int> = 0>
1322
+ basic_fbstring& append(const StringViewLike& like) {
1323
+ string_view_type view = like;
1324
+ return append(view.begin(), view.end());
1325
+ }
1326
+
1327
+ void push_back(const value_type c) { // primitive
1328
+ store_.push_back(c);
1329
+ }
1330
+
1331
+ basic_fbstring& assign(const basic_fbstring& str) {
1332
+ if (&str == this) {
1333
+ return *this;
1334
+ }
1335
+ return assign(str.data(), str.size());
1336
+ }
1337
+
1338
+ basic_fbstring& assign(basic_fbstring&& str) {
1339
+ return *this = std::move(str);
1340
+ }
1341
+
1342
+ basic_fbstring& assign(
1343
+ const basic_fbstring& str, const size_type pos, size_type n);
1344
+
1345
+ basic_fbstring& assign(const value_type* s, const size_type n);
1346
+
1347
+ basic_fbstring& assign(const value_type* s) {
1348
+ return assign(s, traitsLength(s));
1349
+ }
1350
+
1351
+ basic_fbstring& assign(std::initializer_list<value_type> il) {
1352
+ return assign(il.begin(), il.end());
1353
+ }
1354
+
1355
+ template <class ItOrLength, class ItOrChar>
1356
+ basic_fbstring& assign(ItOrLength first_or_n, ItOrChar last_or_c) {
1357
+ return replace(begin(), end(), first_or_n, last_or_c);
1358
+ }
1359
+
1360
+ basic_fbstring& insert(size_type pos1, const basic_fbstring& str) {
1361
+ return insert(pos1, str.data(), str.size());
1362
+ }
1363
+
1364
+ basic_fbstring& insert(
1365
+ size_type pos1, const basic_fbstring& str, size_type pos2, size_type n) {
1366
+ enforce<std::out_of_range>(pos2 <= str.length(), "");
1367
+ procrustes(n, str.length() - pos2);
1368
+ return insert(pos1, str.data() + pos2, n);
1369
+ }
1370
+
1371
+ basic_fbstring& insert(size_type pos, const value_type* s, size_type n) {
1372
+ enforce<std::out_of_range>(pos <= length(), "");
1373
+ insert(begin() + pos, s, s + n);
1374
+ return *this;
1375
+ }
1376
+
1377
+ basic_fbstring& insert(size_type pos, const value_type* s) {
1378
+ return insert(pos, s, traitsLength(s));
1379
+ }
1380
+
1381
+ basic_fbstring& insert(size_type pos, size_type n, value_type c) {
1382
+ enforce<std::out_of_range>(pos <= length(), "");
1383
+ insert(begin() + pos, n, c);
1384
+ return *this;
1385
+ }
1386
+
1387
+ iterator insert(const_iterator p, const value_type c) {
1388
+ const size_type pos = p - cbegin();
1389
+ insert(p, 1, c);
1390
+ return begin() + pos;
1391
+ }
1392
+
1393
+ private:
1394
+ typedef std::basic_istream<value_type, traits_type> istream_type;
1395
+ istream_type& getlineImpl(istream_type& is, value_type delim);
1396
+
1397
+ public:
1398
+ friend inline istream_type& getline(
1399
+ istream_type& is, basic_fbstring& str, value_type delim) {
1400
+ return str.getlineImpl(is, delim);
1401
+ }
1402
+
1403
+ friend inline istream_type& getline(istream_type& is, basic_fbstring& str) {
1404
+ return getline(is, str, '\n');
1405
+ }
1406
+
1407
+ private:
1408
+ iterator insertImplDiscr(
1409
+ const_iterator i, size_type n, value_type c, std::true_type);
1410
+
1411
+ template <class InputIter>
1412
+ iterator insertImplDiscr(
1413
+ const_iterator i, InputIter b, InputIter e, std::false_type);
1414
+
1415
+ template <class FwdIterator>
1416
+ iterator insertImpl(
1417
+ const_iterator i,
1418
+ FwdIterator s1,
1419
+ FwdIterator s2,
1420
+ std::forward_iterator_tag);
1421
+
1422
+ template <class InputIterator>
1423
+ iterator insertImpl(
1424
+ const_iterator i,
1425
+ InputIterator b,
1426
+ InputIterator e,
1427
+ std::input_iterator_tag);
1428
+
1429
+ public:
1430
+ template <class ItOrLength, class ItOrChar>
1431
+ iterator insert(const_iterator p, ItOrLength first_or_n, ItOrChar last_or_c) {
1432
+ using Sel =
1433
+ std::bool_constant<std::numeric_limits<ItOrLength>::is_specialized>;
1434
+ return insertImplDiscr(p, first_or_n, last_or_c, Sel());
1435
+ }
1436
+
1437
+ iterator insert(const_iterator p, std::initializer_list<value_type> il) {
1438
+ return insert(p, il.begin(), il.end());
1439
+ }
1440
+
1441
+ basic_fbstring& erase(size_type pos = 0, size_type n = npos) {
1442
+ Invariant checker(*this);
1443
+
1444
+ enforce<std::out_of_range>(pos <= length(), "");
1445
+ procrustes(n, length() - pos);
1446
+ std::copy(begin() + pos + n, end(), begin() + pos);
1447
+ resize(length() - n);
1448
+ return *this;
1449
+ }
1450
+
1451
+ iterator erase(iterator position) {
1452
+ const size_type pos(position - begin());
1453
+ enforce<std::out_of_range>(pos <= size(), "");
1454
+ erase(pos, 1);
1455
+ return begin() + pos;
1456
+ }
1457
+
1458
+ iterator erase(iterator first, iterator last) {
1459
+ const size_type pos(first - begin());
1460
+ erase(pos, last - first);
1461
+ return begin() + pos;
1462
+ }
1463
+
1464
+ // Replaces at most n1 chars of *this, starting with pos1 with the
1465
+ // content of str
1466
+ basic_fbstring& replace(
1467
+ size_type pos1, size_type n1, const basic_fbstring& str) {
1468
+ return replace(pos1, n1, str.data(), str.size());
1469
+ }
1470
+
1471
+ // Replaces at most n1 chars of *this, starting with pos1,
1472
+ // with at most n2 chars of str starting with pos2
1473
+ basic_fbstring& replace(
1474
+ size_type pos1,
1475
+ size_type n1,
1476
+ const basic_fbstring& str,
1477
+ size_type pos2,
1478
+ size_type n2) {
1479
+ enforce<std::out_of_range>(pos2 <= str.length(), "");
1480
+ return replace(
1481
+ pos1, n1, str.data() + pos2, std::min(n2, str.size() - pos2));
1482
+ }
1483
+
1484
+ // Replaces at most n1 chars of *this, starting with pos, with chars from s
1485
+ basic_fbstring& replace(size_type pos, size_type n1, const value_type* s) {
1486
+ return replace(pos, n1, s, traitsLength(s));
1487
+ }
1488
+
1489
+ // Replaces at most n1 chars of *this, starting with pos, with n2
1490
+ // occurrences of c
1491
+ //
1492
+ // consolidated with
1493
+ //
1494
+ // Replaces at most n1 chars of *this, starting with pos, with at
1495
+ // most n2 chars of str. str must have at least n2 chars.
1496
+ template <class StrOrLength, class NumOrChar>
1497
+ basic_fbstring& replace(
1498
+ size_type pos, size_type n1, StrOrLength s_or_n2, NumOrChar n_or_c) {
1499
+ Invariant checker(*this);
1500
+
1501
+ enforce<std::out_of_range>(pos <= size(), "");
1502
+ procrustes(n1, length() - pos);
1503
+ const iterator b = begin() + pos;
1504
+ return replace(b, b + n1, s_or_n2, n_or_c);
1505
+ }
1506
+
1507
+ basic_fbstring& replace(iterator i1, iterator i2, const basic_fbstring& str) {
1508
+ return replace(i1, i2, str.data(), str.length());
1509
+ }
1510
+
1511
+ basic_fbstring& replace(iterator i1, iterator i2, const value_type* s) {
1512
+ return replace(i1, i2, s, traitsLength(s));
1513
+ }
1514
+
1515
+ private:
1516
+ basic_fbstring& replaceImplDiscr(
1517
+ iterator i1,
1518
+ iterator i2,
1519
+ const value_type* s,
1520
+ size_type n,
1521
+ std::integral_constant<int, 2>);
1522
+
1523
+ basic_fbstring& replaceImplDiscr(
1524
+ iterator i1,
1525
+ iterator i2,
1526
+ size_type n2,
1527
+ value_type c,
1528
+ std::integral_constant<int, 1>);
1529
+
1530
+ template <class InputIter>
1531
+ basic_fbstring& replaceImplDiscr(
1532
+ iterator i1,
1533
+ iterator i2,
1534
+ InputIter b,
1535
+ InputIter e,
1536
+ std::integral_constant<int, 0>);
1537
+
1538
+ private:
1539
+ template <class FwdIterator>
1540
+ bool replaceAliased(
1541
+ iterator /* i1 */,
1542
+ iterator /* i2 */,
1543
+ FwdIterator /* s1 */,
1544
+ FwdIterator /* s2 */,
1545
+ std::false_type) {
1546
+ return false;
1547
+ }
1548
+
1549
+ template <class FwdIterator>
1550
+ bool replaceAliased(
1551
+ iterator i1, iterator i2, FwdIterator s1, FwdIterator s2, std::true_type);
1552
+
1553
+ template <class FwdIterator>
1554
+ void replaceImpl(
1555
+ iterator i1,
1556
+ iterator i2,
1557
+ FwdIterator s1,
1558
+ FwdIterator s2,
1559
+ std::forward_iterator_tag);
1560
+
1561
+ template <class InputIterator>
1562
+ void replaceImpl(
1563
+ iterator i1,
1564
+ iterator i2,
1565
+ InputIterator b,
1566
+ InputIterator e,
1567
+ std::input_iterator_tag);
1568
+
1569
+ public:
1570
+ template <class T1, class T2>
1571
+ basic_fbstring& replace(
1572
+ iterator i1, iterator i2, T1 first_or_n_or_s, T2 last_or_c_or_n) {
1573
+ constexpr bool num1 = std::numeric_limits<T1>::is_specialized,
1574
+ num2 = std::numeric_limits<T2>::is_specialized;
1575
+ using Sel =
1576
+ std::integral_constant<int, num1 ? (num2 ? 1 : -1) : (num2 ? 2 : 0)>;
1577
+ return replaceImplDiscr(i1, i2, first_or_n_or_s, last_or_c_or_n, Sel());
1578
+ }
1579
+
1580
+ size_type copy(value_type* s, size_type n, size_type pos = 0) const {
1581
+ enforce<std::out_of_range>(pos <= size(), "");
1582
+ procrustes(n, size() - pos);
1583
+
1584
+ if (n != 0) {
1585
+ fbstring_detail::podCopy(data() + pos, data() + pos + n, s);
1586
+ }
1587
+ return n;
1588
+ }
1589
+
1590
+ void swap(basic_fbstring& rhs) { store_.swap(rhs.store_); }
1591
+
1592
+ const value_type* c_str() const { return store_.c_str(); }
1593
+
1594
+ const value_type* data() const { return c_str(); }
1595
+
1596
+ value_type* data() { return store_.data(); }
1597
+
1598
+ allocator_type get_allocator() const { return allocator_type(); }
1599
+
1600
+ size_type find(const basic_fbstring& str, size_type pos = 0) const {
1601
+ return find(str.data(), pos, str.length());
1602
+ }
1603
+
1604
+ size_type find(
1605
+ const value_type* needle, size_type pos, size_type nsize) const;
1606
+
1607
+ size_type find(const value_type* s, size_type pos = 0) const {
1608
+ return find(s, pos, traitsLength(s));
1609
+ }
1610
+
1611
+ size_type find(value_type c, size_type pos = 0) const {
1612
+ return find(&c, pos, 1);
1613
+ }
1614
+
1615
+ size_type rfind(const basic_fbstring& str, size_type pos = npos) const {
1616
+ return rfind(str.data(), pos, str.length());
1617
+ }
1618
+
1619
+ size_type rfind(const value_type* s, size_type pos, size_type n) const;
1620
+
1621
+ size_type rfind(const value_type* s, size_type pos = npos) const {
1622
+ return rfind(s, pos, traitsLength(s));
1623
+ }
1624
+
1625
+ size_type rfind(value_type c, size_type pos = npos) const {
1626
+ return rfind(&c, pos, 1);
1627
+ }
1628
+
1629
+ size_type find_first_of(const basic_fbstring& str, size_type pos = 0) const {
1630
+ return find_first_of(str.data(), pos, str.length());
1631
+ }
1632
+
1633
+ size_type find_first_of(
1634
+ const value_type* s, size_type pos, size_type n) const;
1635
+
1636
+ size_type find_first_of(const value_type* s, size_type pos = 0) const {
1637
+ return find_first_of(s, pos, traitsLength(s));
1638
+ }
1639
+
1640
+ size_type find_first_of(value_type c, size_type pos = 0) const {
1641
+ return find_first_of(&c, pos, 1);
1642
+ }
1643
+
1644
+ size_type find_last_of(
1645
+ const basic_fbstring& str, size_type pos = npos) const {
1646
+ return find_last_of(str.data(), pos, str.length());
1647
+ }
1648
+
1649
+ size_type find_last_of(const value_type* s, size_type pos, size_type n) const;
1650
+
1651
+ size_type find_last_of(const value_type* s, size_type pos = npos) const {
1652
+ return find_last_of(s, pos, traitsLength(s));
1653
+ }
1654
+
1655
+ size_type find_last_of(value_type c, size_type pos = npos) const {
1656
+ return find_last_of(&c, pos, 1);
1657
+ }
1658
+
1659
+ size_type find_first_not_of(
1660
+ const basic_fbstring& str, size_type pos = 0) const {
1661
+ return find_first_not_of(str.data(), pos, str.size());
1662
+ }
1663
+
1664
+ size_type find_first_not_of(
1665
+ const value_type* s, size_type pos, size_type n) const;
1666
+
1667
+ size_type find_first_not_of(const value_type* s, size_type pos = 0) const {
1668
+ return find_first_not_of(s, pos, traitsLength(s));
1669
+ }
1670
+
1671
+ size_type find_first_not_of(value_type c, size_type pos = 0) const {
1672
+ return find_first_not_of(&c, pos, 1);
1673
+ }
1674
+
1675
+ size_type find_last_not_of(
1676
+ const basic_fbstring& str, size_type pos = npos) const {
1677
+ return find_last_not_of(str.data(), pos, str.length());
1678
+ }
1679
+
1680
+ size_type find_last_not_of(
1681
+ const value_type* s, size_type pos, size_type n) const;
1682
+
1683
+ size_type find_last_not_of(const value_type* s, size_type pos = npos) const {
1684
+ return find_last_not_of(s, pos, traitsLength(s));
1685
+ }
1686
+
1687
+ size_type find_last_not_of(value_type c, size_type pos = npos) const {
1688
+ return find_last_not_of(&c, pos, 1);
1689
+ }
1690
+
1691
+ basic_fbstring substr(size_type pos = 0, size_type n = npos) const& {
1692
+ enforce<std::out_of_range>(pos <= size(), "");
1693
+ return basic_fbstring(data() + pos, std::min(n, size() - pos));
1694
+ }
1695
+
1696
+ basic_fbstring substr(size_type pos = 0, size_type n = npos) && {
1697
+ enforce<std::out_of_range>(pos <= size(), "");
1698
+ erase(0, pos);
1699
+ if (n < size()) {
1700
+ resize(n);
1701
+ }
1702
+ return std::move(*this);
1703
+ }
1704
+
1705
+ int compare(const basic_fbstring& str) const {
1706
+ // FIX due to Goncalo N M de Carvalho July 18, 2005
1707
+ return compare(0, size(), str);
1708
+ }
1709
+
1710
+ int compare(size_type pos1, size_type n1, const basic_fbstring& str) const {
1711
+ return compare(pos1, n1, str.data(), str.size());
1712
+ }
1713
+
1714
+ int compare(size_type pos1, size_type n1, const value_type* s) const {
1715
+ return compare(pos1, n1, s, traitsLength(s));
1716
+ }
1717
+
1718
+ int compare(
1719
+ size_type pos1, size_type n1, const value_type* s, size_type n2) const {
1720
+ enforce<std::out_of_range>(pos1 <= size(), "");
1721
+ procrustes(n1, size() - pos1);
1722
+ // The line below fixed by Jean-Francois Bastien, 04-23-2007. Thanks!
1723
+ const int r = traits_type::compare(pos1 + data(), s, std::min(n1, n2));
1724
+ return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
1725
+ }
1726
+
1727
+ int compare(
1728
+ size_type pos1,
1729
+ size_type n1,
1730
+ const basic_fbstring& str,
1731
+ size_type pos2,
1732
+ size_type n2) const {
1733
+ enforce<std::out_of_range>(pos2 <= str.size(), "");
1734
+ return compare(
1735
+ pos1, n1, str.data() + pos2, std::min(n2, str.size() - pos2));
1736
+ }
1737
+
1738
+ // Code from Jean-Francois Bastien (03/26/2007)
1739
+ int compare(const value_type* s) const {
1740
+ // Could forward to compare(0, size(), s, traitsLength(s))
1741
+ // but that does two extra checks
1742
+ const size_type n1(size()), n2(traitsLength(s));
1743
+ const int r = traits_type::compare(data(), s, std::min(n1, n2));
1744
+ return r != 0 ? r : n1 > n2 ? 1 : n1 < n2 ? -1 : 0;
1745
+ }
1746
+
1747
+ #if FOLLY_CPLUSPLUS >= 202002L
1748
+ friend auto operator<=>(
1749
+ const basic_fbstring& lhs, const basic_fbstring& rhs) {
1750
+ return lhs.spaceship(rhs.data(), rhs.size());
1751
+ }
1752
+ friend auto operator<=>(const basic_fbstring& lhs, const char* rhs) {
1753
+ return lhs.spaceship(rhs, traitsLength(rhs));
1754
+ }
1755
+ template <typename A2>
1756
+ friend auto operator<=>(
1757
+ const basic_fbstring& lhs, const std::basic_string<E, T, A2>& rhs) {
1758
+ return lhs.spaceship(rhs.data(), rhs.size());
1759
+ }
1760
+ #endif // FOLLY_CPLUSPLUS >= 202002L
1761
+
1762
+ private:
1763
+ #if FOLLY_CPLUSPLUS >= 202002L
1764
+ auto spaceship(const value_type* rhsData, size_type rhsSize) const {
1765
+ auto c = compare(0, size(), rhsData, rhsSize);
1766
+ if (c == 0) {
1767
+ return std::strong_ordering::equal;
1768
+ } else if (c < 0) {
1769
+ return std::strong_ordering::less;
1770
+ } else {
1771
+ return std::strong_ordering::greater;
1772
+ }
1773
+ }
1774
+ #endif // FOLLY_CPLUSPLUS >= 202002L
1775
+
1776
+ // Data
1777
+ Storage store_;
1778
+ };
1779
+
1780
+ template <typename E, class T, class A, class S>
1781
+ FOLLY_NOINLINE typename basic_fbstring<E, T, A, S>::size_type
1782
+ basic_fbstring<E, T, A, S>::traitsLength(const value_type* s) {
1783
+ return s ? traits_type::length(s)
1784
+ : (throw_exception<std::logic_error>(
1785
+ "basic_fbstring: null pointer initializer not valid"),
1786
+ 0);
1787
+ }
1788
+
1789
+ template <typename E, class T, class A, class S>
1790
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::operator=(
1791
+ const basic_fbstring& lhs) {
1792
+ Invariant checker(*this);
1793
+
1794
+ if (FOLLY_UNLIKELY(&lhs == this)) {
1795
+ return *this;
1796
+ }
1797
+
1798
+ return assign(lhs.data(), lhs.size());
1799
+ }
1800
+
1801
+ // Move assignment
1802
+ template <typename E, class T, class A, class S>
1803
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::operator=(
1804
+ basic_fbstring&& goner) noexcept {
1805
+ if (FOLLY_UNLIKELY(&goner == this)) {
1806
+ // Compatibility with std::basic_string<>,
1807
+ // C++11 21.4.2 [string.cons] / 23 requires self-move-assignment support.
1808
+ return *this;
1809
+ }
1810
+ // No need of this anymore
1811
+ this->~basic_fbstring();
1812
+ // Move the goner into this
1813
+ new (&store_) S(std::move(goner.store_));
1814
+ return *this;
1815
+ }
1816
+
1817
+ template <typename E, class T, class A, class S>
1818
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::operator=(
1819
+ value_type c) {
1820
+ Invariant checker(*this);
1821
+
1822
+ if (empty()) {
1823
+ store_.expandNoinit(1);
1824
+ } else if (store_.isShared()) {
1825
+ basic_fbstring(1, c).swap(*this);
1826
+ return *this;
1827
+ } else {
1828
+ store_.shrink(size() - 1);
1829
+ }
1830
+ front() = c;
1831
+ return *this;
1832
+ }
1833
+
1834
+ template <typename E, class T, class A, class S>
1835
+ inline void basic_fbstring<E, T, A, S>::resize(
1836
+ const size_type n, const value_type c /*= value_type()*/) {
1837
+ Invariant checker(*this);
1838
+
1839
+ auto size = this->size();
1840
+ if (n <= size) {
1841
+ store_.shrink(size - n);
1842
+ } else {
1843
+ auto const delta = n - size;
1844
+ auto pData = store_.expandNoinit(delta);
1845
+ fbstring_detail::podFill(pData, pData + delta, c);
1846
+ }
1847
+ assert(this->size() == n);
1848
+ }
1849
+
1850
+ template <typename E, class T, class A, class S>
1851
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
1852
+ const basic_fbstring& str) {
1853
+ #ifndef NDEBUG
1854
+ auto desiredSize = size() + str.size();
1855
+ #endif
1856
+ append(str.data(), str.size());
1857
+ assert(size() == desiredSize);
1858
+ return *this;
1859
+ }
1860
+
1861
+ template <typename E, class T, class A, class S>
1862
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
1863
+ const basic_fbstring& str, const size_type pos, size_type n) {
1864
+ const size_type sz = str.size();
1865
+ enforce<std::out_of_range>(pos <= sz, "");
1866
+ procrustes(n, sz - pos);
1867
+ return append(str.data() + pos, n);
1868
+ }
1869
+
1870
+ template <typename E, class T, class A, class S>
1871
+ FOLLY_NOINLINE basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
1872
+ const value_type* s, size_type n) {
1873
+ Invariant checker(*this);
1874
+
1875
+ if (FOLLY_UNLIKELY(!n)) {
1876
+ // Unlikely but must be done
1877
+ return *this;
1878
+ }
1879
+ auto const oldSize = size();
1880
+ auto const oldData = data();
1881
+ auto pData = store_.expandNoinit(n, /* expGrowth = */ true);
1882
+
1883
+ // Check for aliasing (rare). We could use "<=" here but in theory
1884
+ // those do not work for pointers unless the pointers point to
1885
+ // elements in the same array. For that reason we use
1886
+ // std::less_equal, which is guaranteed to offer a total order
1887
+ // over pointers. See discussion at http://goo.gl/Cy2ya for more
1888
+ // info.
1889
+ std::less_equal<const value_type*> le;
1890
+ if (FOLLY_UNLIKELY(le(oldData, s) && !le(oldData + oldSize, s))) {
1891
+ assert(le(s + n, oldData + oldSize));
1892
+ // expandNoinit() could have moved the storage, restore the source.
1893
+ s = data() + (s - oldData);
1894
+ fbstring_detail::podMove(s, s + n, pData);
1895
+ } else {
1896
+ fbstring_detail::podCopy(s, s + n, pData);
1897
+ }
1898
+
1899
+ assert(size() == oldSize + n);
1900
+ return *this;
1901
+ }
1902
+
1903
+ template <typename E, class T, class A, class S>
1904
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
1905
+ size_type n, value_type c) {
1906
+ Invariant checker(*this);
1907
+ auto pData = store_.expandNoinit(n, /* expGrowth = */ true);
1908
+ fbstring_detail::podFill(pData, pData + n, c);
1909
+ return *this;
1910
+ }
1911
+
1912
+ template <typename E, class T, class A, class S>
1913
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::assign(
1914
+ const basic_fbstring& str, const size_type pos, size_type n) {
1915
+ const size_type sz = str.size();
1916
+ enforce<std::out_of_range>(pos <= sz, "");
1917
+ procrustes(n, sz - pos);
1918
+ return assign(str.data() + pos, n);
1919
+ }
1920
+
1921
+ template <typename E, class T, class A, class S>
1922
+ FOLLY_NOINLINE basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::assign(
1923
+ const value_type* s, const size_type n) {
1924
+ Invariant checker(*this);
1925
+
1926
+ if (n == 0) {
1927
+ resize(0);
1928
+ } else if (size() >= n) {
1929
+ // s can alias this, we need to use podMove.
1930
+ fbstring_detail::podMove(s, s + n, store_.mutableData());
1931
+ store_.shrink(size() - n);
1932
+ assert(size() == n);
1933
+ } else {
1934
+ // If n is larger than size(), s cannot alias this string's
1935
+ // storage.
1936
+ resize(0);
1937
+ // Do not use exponential growth here: assign() should be tight,
1938
+ // to mirror the behavior of the equivalent constructor.
1939
+ fbstring_detail::podCopy(s, s + n, store_.expandNoinit(n));
1940
+ }
1941
+
1942
+ assert(size() == n);
1943
+ return *this;
1944
+ }
1945
+
1946
+ template <typename E, class T, class A, class S>
1947
+ inline typename basic_fbstring<E, T, A, S>::istream_type&
1948
+ basic_fbstring<E, T, A, S>::getlineImpl(istream_type& is, value_type delim) {
1949
+ Invariant checker(*this);
1950
+
1951
+ clear();
1952
+ size_t size = 0;
1953
+ while (true) {
1954
+ size_t avail = capacity() - size;
1955
+ // fbstring has 1 byte extra capacity for the null terminator,
1956
+ // and getline null-terminates the read string.
1957
+ is.getline(store_.expandNoinit(avail), avail + 1, delim);
1958
+ size += is.gcount();
1959
+
1960
+ if (is.bad() || is.eof() || !is.fail()) {
1961
+ // Done by either failure, end of file, or normal read.
1962
+ if (!is.bad() && !is.eof()) {
1963
+ --size; // gcount() also accounts for the delimiter.
1964
+ }
1965
+ resize(size);
1966
+ break;
1967
+ }
1968
+
1969
+ assert(size == this->size());
1970
+ assert(size == capacity());
1971
+ // Start at minimum allocation 63 + terminator = 64.
1972
+ reserve(std::max<size_t>(63, 3 * size / 2));
1973
+ // Clear the error so we can continue reading.
1974
+ is.clear();
1975
+ }
1976
+ return is;
1977
+ }
1978
+
1979
+ template <typename E, class T, class A, class S>
1980
+ inline typename basic_fbstring<E, T, A, S>::size_type
1981
+ basic_fbstring<E, T, A, S>::find(
1982
+ const value_type* needle,
1983
+ const size_type pos,
1984
+ const size_type nsize) const {
1985
+ auto const size = this->size();
1986
+ // nsize + pos can overflow (eg pos == npos), guard against that by checking
1987
+ // that nsize + pos does not wrap around.
1988
+ if (nsize + pos > size || nsize + pos < pos) {
1989
+ return npos;
1990
+ }
1991
+
1992
+ if (nsize == 0) {
1993
+ return pos;
1994
+ }
1995
+ // Don't use std::search, use a Boyer-Moore-like trick by comparing
1996
+ // the last characters first
1997
+ auto const haystack = data();
1998
+ auto const nsize_1 = nsize - 1;
1999
+ auto const lastNeedle = needle[nsize_1];
2000
+
2001
+ // Boyer-Moore skip value for the last char in the needle. Zero is
2002
+ // not a valid value; skip will be computed the first time it's
2003
+ // needed.
2004
+ size_type skip = 0;
2005
+
2006
+ const E* i = haystack + pos;
2007
+ auto iEnd = haystack + size - nsize_1;
2008
+
2009
+ while (i < iEnd) {
2010
+ // Boyer-Moore: match the last element in the needle
2011
+ while (i[nsize_1] != lastNeedle) {
2012
+ if (++i == iEnd) {
2013
+ // not found
2014
+ return npos;
2015
+ }
2016
+ }
2017
+ // Here we know that the last char matches
2018
+ // Continue in pedestrian mode
2019
+ for (size_t j = 0;;) {
2020
+ assert(j < nsize);
2021
+ if (i[j] != needle[j]) {
2022
+ // Not found, we can skip
2023
+ // Compute the skip value lazily
2024
+ if (skip == 0) {
2025
+ skip = 1;
2026
+ while (skip <= nsize_1 && needle[nsize_1 - skip] != lastNeedle) {
2027
+ ++skip;
2028
+ }
2029
+ }
2030
+ i += skip;
2031
+ break;
2032
+ }
2033
+ // Check if done searching
2034
+ if (++j == nsize) {
2035
+ // Yay
2036
+ return i - haystack;
2037
+ }
2038
+ }
2039
+ }
2040
+ return npos;
2041
+ }
2042
+
2043
+ template <typename E, class T, class A, class S>
2044
+ inline typename basic_fbstring<E, T, A, S>::iterator
2045
+ basic_fbstring<E, T, A, S>::insertImplDiscr(
2046
+ const_iterator i, size_type n, value_type c, std::true_type) {
2047
+ Invariant checker(*this);
2048
+
2049
+ assert(i >= cbegin() && i <= cend());
2050
+ const size_type pos = i - cbegin();
2051
+
2052
+ auto oldSize = size();
2053
+ store_.expandNoinit(n, /* expGrowth = */ true);
2054
+ auto b = begin();
2055
+ fbstring_detail::podMove(b + pos, b + oldSize, b + pos + n);
2056
+ fbstring_detail::podFill(b + pos, b + pos + n, c);
2057
+
2058
+ return b + pos;
2059
+ }
2060
+
2061
+ template <typename E, class T, class A, class S>
2062
+ template <class InputIter>
2063
+ inline typename basic_fbstring<E, T, A, S>::iterator
2064
+ basic_fbstring<E, T, A, S>::insertImplDiscr(
2065
+ const_iterator i, InputIter b, InputIter e, std::false_type) {
2066
+ return insertImpl(
2067
+ i, b, e, typename std::iterator_traits<InputIter>::iterator_category());
2068
+ }
2069
+
2070
+ template <typename E, class T, class A, class S>
2071
+ template <class FwdIterator>
2072
+ inline typename basic_fbstring<E, T, A, S>::iterator
2073
+ basic_fbstring<E, T, A, S>::insertImpl(
2074
+ const_iterator i,
2075
+ FwdIterator s1,
2076
+ FwdIterator s2,
2077
+ std::forward_iterator_tag) {
2078
+ Invariant checker(*this);
2079
+
2080
+ assert(i >= cbegin() && i <= cend());
2081
+ const size_type pos = i - cbegin();
2082
+ auto n = std::distance(s1, s2);
2083
+ assert(n >= 0);
2084
+
2085
+ auto oldSize = size();
2086
+ store_.expandNoinit(n, /* expGrowth = */ true);
2087
+ auto b = begin();
2088
+ fbstring_detail::podMove(b + pos, b + oldSize, b + pos + n);
2089
+ std::copy(s1, s2, b + pos);
2090
+
2091
+ return b + pos;
2092
+ }
2093
+
2094
+ template <typename E, class T, class A, class S>
2095
+ template <class InputIterator>
2096
+ inline typename basic_fbstring<E, T, A, S>::iterator
2097
+ basic_fbstring<E, T, A, S>::insertImpl(
2098
+ const_iterator i,
2099
+ InputIterator b,
2100
+ InputIterator e,
2101
+ std::input_iterator_tag) {
2102
+ const auto pos = i - cbegin();
2103
+ basic_fbstring temp(cbegin(), i);
2104
+ for (; b != e; ++b) {
2105
+ temp.push_back(*b);
2106
+ }
2107
+ temp.append(i, cend());
2108
+ swap(temp);
2109
+ return begin() + pos;
2110
+ }
2111
+
2112
+ template <typename E, class T, class A, class S>
2113
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::replaceImplDiscr(
2114
+ iterator i1,
2115
+ iterator i2,
2116
+ const value_type* s,
2117
+ size_type n,
2118
+ std::integral_constant<int, 2>) {
2119
+ assert(i1 <= i2);
2120
+ assert(begin() <= i1 && i1 <= end());
2121
+ assert(begin() <= i2 && i2 <= end());
2122
+ return replace(i1, i2, s, s + n);
2123
+ }
2124
+
2125
+ template <typename E, class T, class A, class S>
2126
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::replaceImplDiscr(
2127
+ iterator i1,
2128
+ iterator i2,
2129
+ size_type n2,
2130
+ value_type c,
2131
+ std::integral_constant<int, 1>) {
2132
+ const size_type n1 = i2 - i1;
2133
+ if (n1 > n2) {
2134
+ std::fill(i1, i1 + n2, c);
2135
+ erase(i1 + n2, i2);
2136
+ } else {
2137
+ std::fill(i1, i2, c);
2138
+ insert(i2, n2 - n1, c);
2139
+ }
2140
+ assert(isSane());
2141
+ return *this;
2142
+ }
2143
+
2144
+ template <typename E, class T, class A, class S>
2145
+ template <class InputIter>
2146
+ inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::replaceImplDiscr(
2147
+ iterator i1,
2148
+ iterator i2,
2149
+ InputIter b,
2150
+ InputIter e,
2151
+ std::integral_constant<int, 0>) {
2152
+ using Cat = typename std::iterator_traits<InputIter>::iterator_category;
2153
+ replaceImpl(i1, i2, b, e, Cat());
2154
+ return *this;
2155
+ }
2156
+
2157
+ template <typename E, class T, class A, class S>
2158
+ template <class FwdIterator>
2159
+ inline bool basic_fbstring<E, T, A, S>::replaceAliased(
2160
+ iterator i1, iterator i2, FwdIterator s1, FwdIterator s2, std::true_type) {
2161
+ std::less_equal<const value_type*> le{};
2162
+ const bool aliased = le(&*begin(), &*s1) && le(&*s1, &*end());
2163
+ if (!aliased) {
2164
+ return false;
2165
+ }
2166
+ // Aliased replace, copy to new string
2167
+ basic_fbstring temp;
2168
+ temp.reserve(size() - (i2 - i1) + std::distance(s1, s2));
2169
+ temp.append(begin(), i1).append(s1, s2).append(i2, end());
2170
+ swap(temp);
2171
+ return true;
2172
+ }
2173
+
2174
+ template <typename E, class T, class A, class S>
2175
+ template <class FwdIterator>
2176
+ inline void basic_fbstring<E, T, A, S>::replaceImpl(
2177
+ iterator i1,
2178
+ iterator i2,
2179
+ FwdIterator s1,
2180
+ FwdIterator s2,
2181
+ std::forward_iterator_tag) {
2182
+ Invariant checker(*this);
2183
+
2184
+ // Handle aliased replace
2185
+ using Sel = std::bool_constant<
2186
+ std::is_same<FwdIterator, iterator>::value ||
2187
+ std::is_same<FwdIterator, const_iterator>::value>;
2188
+ if (replaceAliased(i1, i2, s1, s2, Sel())) {
2189
+ return;
2190
+ }
2191
+
2192
+ auto const n1 = i2 - i1;
2193
+ assert(n1 >= 0);
2194
+ auto const n2 = std::distance(s1, s2);
2195
+ assert(n2 >= 0);
2196
+
2197
+ if (n1 > n2) {
2198
+ // shrinks
2199
+ std::copy(s1, s2, i1);
2200
+ erase(i1 + n2, i2);
2201
+ } else {
2202
+ // grows
2203
+ s1 = fbstring_detail::copy_n(s1, n1, i1).first;
2204
+ insert(i2, s1, s2);
2205
+ }
2206
+ assert(isSane());
2207
+ }
2208
+
2209
+ template <typename E, class T, class A, class S>
2210
+ template <class InputIterator>
2211
+ inline void basic_fbstring<E, T, A, S>::replaceImpl(
2212
+ iterator i1,
2213
+ iterator i2,
2214
+ InputIterator b,
2215
+ InputIterator e,
2216
+ std::input_iterator_tag) {
2217
+ basic_fbstring temp(begin(), i1);
2218
+ temp.append(b, e).append(i2, end());
2219
+ swap(temp);
2220
+ }
2221
+
2222
+ template <typename E, class T, class A, class S>
2223
+ inline typename basic_fbstring<E, T, A, S>::size_type
2224
+ basic_fbstring<E, T, A, S>::rfind(
2225
+ const value_type* s, size_type pos, size_type n) const {
2226
+ if (n > length()) {
2227
+ return npos;
2228
+ }
2229
+ pos = std::min(pos, length() - n);
2230
+ if (n == 0) {
2231
+ return pos;
2232
+ }
2233
+
2234
+ const_iterator i(begin() + pos);
2235
+ for (;; --i) {
2236
+ if (traits_type::eq(*i, *s) && traits_type::compare(&*i, s, n) == 0) {
2237
+ return i - begin();
2238
+ }
2239
+ if (i == begin()) {
2240
+ break;
2241
+ }
2242
+ }
2243
+ return npos;
2244
+ }
2245
+
2246
+ template <typename E, class T, class A, class S>
2247
+ inline typename basic_fbstring<E, T, A, S>::size_type
2248
+ basic_fbstring<E, T, A, S>::find_first_of(
2249
+ const value_type* s, size_type pos, size_type n) const {
2250
+ if (pos > length() || n == 0) {
2251
+ return npos;
2252
+ }
2253
+ const_iterator i(begin() + pos), finish(end());
2254
+ for (; i != finish; ++i) {
2255
+ if (traits_type::find(s, n, *i) != nullptr) {
2256
+ return i - begin();
2257
+ }
2258
+ }
2259
+ return npos;
2260
+ }
2261
+
2262
+ template <typename E, class T, class A, class S>
2263
+ inline typename basic_fbstring<E, T, A, S>::size_type
2264
+ basic_fbstring<E, T, A, S>::find_last_of(
2265
+ const value_type* s, size_type pos, size_type n) const {
2266
+ if (!empty() && n > 0) {
2267
+ pos = std::min(pos, length() - 1);
2268
+ const_iterator i(begin() + pos);
2269
+ for (;; --i) {
2270
+ if (traits_type::find(s, n, *i) != nullptr) {
2271
+ return i - begin();
2272
+ }
2273
+ if (i == begin()) {
2274
+ break;
2275
+ }
2276
+ }
2277
+ }
2278
+ return npos;
2279
+ }
2280
+
2281
+ template <typename E, class T, class A, class S>
2282
+ inline typename basic_fbstring<E, T, A, S>::size_type
2283
+ basic_fbstring<E, T, A, S>::find_first_not_of(
2284
+ const value_type* s, size_type pos, size_type n) const {
2285
+ if (pos < length()) {
2286
+ const_iterator i(begin() + pos), finish(end());
2287
+ for (; i != finish; ++i) {
2288
+ if (traits_type::find(s, n, *i) == nullptr) {
2289
+ return i - begin();
2290
+ }
2291
+ }
2292
+ }
2293
+ return npos;
2294
+ }
2295
+
2296
+ template <typename E, class T, class A, class S>
2297
+ inline typename basic_fbstring<E, T, A, S>::size_type
2298
+ basic_fbstring<E, T, A, S>::find_last_not_of(
2299
+ const value_type* s, size_type pos, size_type n) const {
2300
+ if (!this->empty()) {
2301
+ pos = std::min(pos, size() - 1);
2302
+ const_iterator i(begin() + pos);
2303
+ for (;; --i) {
2304
+ if (traits_type::find(s, n, *i) == nullptr) {
2305
+ return i - begin();
2306
+ }
2307
+ if (i == begin()) {
2308
+ break;
2309
+ }
2310
+ }
2311
+ }
2312
+ return npos;
2313
+ }
2314
+
2315
+ // non-member functions
2316
+ // C++11 21.4.8.1/1
2317
+ template <typename E, class T, class A, class S>
2318
+ inline basic_fbstring<E, T, A, S> operator+(
2319
+ const basic_fbstring<E, T, A, S>& lhs,
2320
+ const basic_fbstring<E, T, A, S>& rhs) {
2321
+ basic_fbstring<E, T, A, S> result;
2322
+ result.reserve(lhs.size() + rhs.size());
2323
+ result.append(lhs).append(rhs);
2324
+ return result;
2325
+ }
2326
+
2327
+ // C++11 21.4.8.1/2
2328
+ template <typename E, class T, class A, class S>
2329
+ inline basic_fbstring<E, T, A, S> operator+(
2330
+ basic_fbstring<E, T, A, S>&& lhs, const basic_fbstring<E, T, A, S>& rhs) {
2331
+ return std::move(lhs.append(rhs));
2332
+ }
2333
+
2334
+ // C++11 21.4.8.1/3
2335
+ template <typename E, class T, class A, class S>
2336
+ inline basic_fbstring<E, T, A, S> operator+(
2337
+ const basic_fbstring<E, T, A, S>& lhs, basic_fbstring<E, T, A, S>&& rhs) {
2338
+ if (rhs.capacity() >= lhs.size() + rhs.size()) {
2339
+ // Good, at least we don't need to reallocate
2340
+ return std::move(rhs.insert(0, lhs));
2341
+ }
2342
+ // Meh, no go. Forward to operator+(const&, const&).
2343
+ auto const& rhsC = rhs;
2344
+ return lhs + rhsC;
2345
+ }
2346
+
2347
+ // C++11 21.4.8.1/4
2348
+ template <typename E, class T, class A, class S>
2349
+ inline basic_fbstring<E, T, A, S> operator+(
2350
+ basic_fbstring<E, T, A, S>&& lhs, basic_fbstring<E, T, A, S>&& rhs) {
2351
+ return std::move(lhs.append(rhs));
2352
+ }
2353
+
2354
+ // C++11 21.4.8.1/5
2355
+ template <typename E, class T, class A, class S>
2356
+ inline basic_fbstring<E, T, A, S> operator+(
2357
+ const E* lhs, const basic_fbstring<E, T, A, S>& rhs) {
2358
+ //
2359
+ basic_fbstring<E, T, A, S> result;
2360
+ const auto len = basic_fbstring<E, T, A, S>::traits_type::length(lhs);
2361
+ result.reserve(len + rhs.size());
2362
+ result.append(lhs, len).append(rhs);
2363
+ return result;
2364
+ }
2365
+
2366
+ // C++11 21.4.8.1/6
2367
+ template <typename E, class T, class A, class S>
2368
+ inline basic_fbstring<E, T, A, S> operator+(
2369
+ const E* lhs, basic_fbstring<E, T, A, S>&& rhs) {
2370
+ //
2371
+ const auto len = basic_fbstring<E, T, A, S>::traits_type::length(lhs);
2372
+ if (rhs.capacity() >= len + rhs.size()) {
2373
+ // Good, at least we don't need to reallocate
2374
+ rhs.insert(rhs.begin(), lhs, lhs + len);
2375
+ return std::move(rhs);
2376
+ }
2377
+ // Meh, no go. Do it by hand since we have len already.
2378
+ basic_fbstring<E, T, A, S> result;
2379
+ result.reserve(len + rhs.size());
2380
+ result.append(lhs, len).append(rhs);
2381
+ return result;
2382
+ }
2383
+
2384
+ // C++11 21.4.8.1/7
2385
+ template <typename E, class T, class A, class S>
2386
+ inline basic_fbstring<E, T, A, S> operator+(
2387
+ E lhs, const basic_fbstring<E, T, A, S>& rhs) {
2388
+ basic_fbstring<E, T, A, S> result;
2389
+ result.reserve(1 + rhs.size());
2390
+ result.push_back(lhs);
2391
+ result.append(rhs);
2392
+ return result;
2393
+ }
2394
+
2395
+ // C++11 21.4.8.1/8
2396
+ template <typename E, class T, class A, class S>
2397
+ inline basic_fbstring<E, T, A, S> operator+(
2398
+ E lhs, basic_fbstring<E, T, A, S>&& rhs) {
2399
+ //
2400
+ if (rhs.capacity() > rhs.size()) {
2401
+ // Good, at least we don't need to reallocate
2402
+ rhs.insert(rhs.begin(), lhs);
2403
+ return std::move(rhs);
2404
+ }
2405
+ // Meh, no go. Forward to operator+(E, const&).
2406
+ auto const& rhsC = rhs;
2407
+ return lhs + rhsC;
2408
+ }
2409
+
2410
+ // C++11 21.4.8.1/9
2411
+ template <typename E, class T, class A, class S>
2412
+ inline basic_fbstring<E, T, A, S> operator+(
2413
+ const basic_fbstring<E, T, A, S>& lhs, const E* rhs) {
2414
+ typedef typename basic_fbstring<E, T, A, S>::size_type size_type;
2415
+ typedef typename basic_fbstring<E, T, A, S>::traits_type traits_type;
2416
+
2417
+ basic_fbstring<E, T, A, S> result;
2418
+ const size_type len = traits_type::length(rhs);
2419
+ result.reserve(lhs.size() + len);
2420
+ result.append(lhs).append(rhs, len);
2421
+ return result;
2422
+ }
2423
+
2424
+ // C++11 21.4.8.1/10
2425
+ template <typename E, class T, class A, class S>
2426
+ inline basic_fbstring<E, T, A, S> operator+(
2427
+ basic_fbstring<E, T, A, S>&& lhs, const E* rhs) {
2428
+ //
2429
+ return std::move(lhs += rhs);
2430
+ }
2431
+
2432
+ // C++11 21.4.8.1/11
2433
+ template <typename E, class T, class A, class S>
2434
+ inline basic_fbstring<E, T, A, S> operator+(
2435
+ const basic_fbstring<E, T, A, S>& lhs, E rhs) {
2436
+ basic_fbstring<E, T, A, S> result;
2437
+ result.reserve(lhs.size() + 1);
2438
+ result.append(lhs);
2439
+ result.push_back(rhs);
2440
+ return result;
2441
+ }
2442
+
2443
+ // C++11 21.4.8.1/12
2444
+ template <typename E, class T, class A, class S>
2445
+ inline basic_fbstring<E, T, A, S> operator+(
2446
+ basic_fbstring<E, T, A, S>&& lhs, E rhs) {
2447
+ //
2448
+ return std::move(lhs += rhs);
2449
+ }
2450
+
2451
+ template <typename E, class T, class A, class S>
2452
+ inline bool operator==(
2453
+ const basic_fbstring<E, T, A, S>& lhs,
2454
+ const basic_fbstring<E, T, A, S>& rhs) {
2455
+ return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
2456
+ }
2457
+
2458
+ template <typename E, class T, class A, class S>
2459
+ inline bool operator==(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2460
+ delete;
2461
+
2462
+ template <typename E, class T, class A, class S>
2463
+ inline bool operator==(
2464
+ const typename basic_fbstring<E, T, A, S>::value_type* lhs,
2465
+ const basic_fbstring<E, T, A, S>& rhs) {
2466
+ return rhs == lhs;
2467
+ }
2468
+
2469
+ template <typename E, class T, class A, class S>
2470
+ inline bool operator==(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2471
+ delete;
2472
+
2473
+ template <typename E, class T, class A, class S>
2474
+ inline bool operator==(
2475
+ const basic_fbstring<E, T, A, S>& lhs,
2476
+ const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
2477
+ return lhs.compare(rhs) == 0;
2478
+ }
2479
+
2480
+ template <typename E, class T, class A, class S>
2481
+ inline bool operator!=(
2482
+ const basic_fbstring<E, T, A, S>& lhs,
2483
+ const basic_fbstring<E, T, A, S>& rhs) {
2484
+ return !(lhs == rhs);
2485
+ }
2486
+
2487
+ template <typename E, class T, class A, class S>
2488
+ inline bool operator!=(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2489
+ delete;
2490
+
2491
+ template <typename E, class T, class A, class S>
2492
+ inline bool operator!=(
2493
+ const typename basic_fbstring<E, T, A, S>::value_type* lhs,
2494
+ const basic_fbstring<E, T, A, S>& rhs) {
2495
+ return !(lhs == rhs);
2496
+ }
2497
+
2498
+ template <typename E, class T, class A, class S>
2499
+ inline bool operator!=(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2500
+ delete;
2501
+
2502
+ template <typename E, class T, class A, class S>
2503
+ inline bool operator!=(
2504
+ const basic_fbstring<E, T, A, S>& lhs,
2505
+ const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
2506
+ return !(lhs == rhs);
2507
+ }
2508
+
2509
+ template <typename E, class T, class A, class S>
2510
+ inline bool operator<(
2511
+ const basic_fbstring<E, T, A, S>& lhs,
2512
+ const basic_fbstring<E, T, A, S>& rhs) {
2513
+ return lhs.compare(rhs) < 0;
2514
+ }
2515
+
2516
+ template <typename E, class T, class A, class S>
2517
+ inline bool operator<(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2518
+ delete;
2519
+
2520
+ template <typename E, class T, class A, class S>
2521
+ inline bool operator<(
2522
+ const basic_fbstring<E, T, A, S>& lhs,
2523
+ const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
2524
+ return lhs.compare(rhs) < 0;
2525
+ }
2526
+
2527
+ template <typename E, class T, class A, class S>
2528
+ inline bool operator<(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2529
+ delete;
2530
+
2531
+ template <typename E, class T, class A, class S>
2532
+ inline bool operator<(
2533
+ const typename basic_fbstring<E, T, A, S>::value_type* lhs,
2534
+ const basic_fbstring<E, T, A, S>& rhs) {
2535
+ return rhs.compare(lhs) > 0;
2536
+ }
2537
+
2538
+ template <typename E, class T, class A, class S>
2539
+ inline bool operator>(
2540
+ const basic_fbstring<E, T, A, S>& lhs,
2541
+ const basic_fbstring<E, T, A, S>& rhs) {
2542
+ return rhs < lhs;
2543
+ }
2544
+
2545
+ template <typename E, class T, class A, class S>
2546
+ inline bool operator>(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2547
+ delete;
2548
+
2549
+ template <typename E, class T, class A, class S>
2550
+ inline bool operator>(
2551
+ const basic_fbstring<E, T, A, S>& lhs,
2552
+ const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
2553
+ return rhs < lhs;
2554
+ }
2555
+
2556
+ template <typename E, class T, class A, class S>
2557
+ inline bool operator>(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2558
+ delete;
2559
+
2560
+ template <typename E, class T, class A, class S>
2561
+ inline bool operator>(
2562
+ const typename basic_fbstring<E, T, A, S>::value_type* lhs,
2563
+ const basic_fbstring<E, T, A, S>& rhs) {
2564
+ return rhs < lhs;
2565
+ }
2566
+
2567
+ template <typename E, class T, class A, class S>
2568
+ inline bool operator<=(
2569
+ const basic_fbstring<E, T, A, S>& lhs,
2570
+ const basic_fbstring<E, T, A, S>& rhs) {
2571
+ return !(rhs < lhs);
2572
+ }
2573
+
2574
+ template <typename E, class T, class A, class S>
2575
+ inline bool operator<=(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2576
+ delete;
2577
+
2578
+ template <typename E, class T, class A, class S>
2579
+ inline bool operator<=(
2580
+ const basic_fbstring<E, T, A, S>& lhs,
2581
+ const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
2582
+ return !(rhs < lhs);
2583
+ }
2584
+
2585
+ template <typename E, class T, class A, class S>
2586
+ inline bool operator<=(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2587
+ delete;
2588
+
2589
+ template <typename E, class T, class A, class S>
2590
+ inline bool operator<=(
2591
+ const typename basic_fbstring<E, T, A, S>::value_type* lhs,
2592
+ const basic_fbstring<E, T, A, S>& rhs) {
2593
+ return !(rhs < lhs);
2594
+ }
2595
+
2596
+ template <typename E, class T, class A, class S>
2597
+ inline bool operator>=(
2598
+ const basic_fbstring<E, T, A, S>& lhs,
2599
+ const basic_fbstring<E, T, A, S>& rhs) {
2600
+ return !(lhs < rhs);
2601
+ }
2602
+
2603
+ template <typename E, class T, class A, class S>
2604
+ inline bool operator>=(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2605
+ delete;
2606
+
2607
+ template <typename E, class T, class A, class S>
2608
+ inline bool operator>=(
2609
+ const basic_fbstring<E, T, A, S>& lhs,
2610
+ const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
2611
+ return !(lhs < rhs);
2612
+ }
2613
+
2614
+ template <typename E, class T, class A, class S>
2615
+ inline bool operator>=(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2616
+ delete;
2617
+
2618
+ template <typename E, class T, class A, class S>
2619
+ inline bool operator>=(
2620
+ const typename basic_fbstring<E, T, A, S>::value_type* lhs,
2621
+ const basic_fbstring<E, T, A, S>& rhs) {
2622
+ return !(lhs < rhs);
2623
+ }
2624
+
2625
+ #if FOLLY_CPLUSPLUS >= 202002
2626
+ template <typename E, class T, class A, class S>
2627
+ inline bool operator<=>(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
2628
+ delete;
2629
+
2630
+ template <typename E, class T, class A, class S>
2631
+ inline bool operator<=>(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
2632
+ delete;
2633
+ #endif
2634
+
2635
+ // C++11 21.4.8.8
2636
+ template <typename E, class T, class A, class S>
2637
+ void swap(basic_fbstring<E, T, A, S>& lhs, basic_fbstring<E, T, A, S>& rhs) {
2638
+ lhs.swap(rhs);
2639
+ }
2640
+
2641
+ // TODO: make this faster.
2642
+ template <typename E, class T, class A, class S>
2643
+ inline std::basic_istream<
2644
+ typename basic_fbstring<E, T, A, S>::value_type,
2645
+ typename basic_fbstring<E, T, A, S>::traits_type>&
2646
+ operator>>(
2647
+ std::basic_istream<
2648
+ typename basic_fbstring<E, T, A, S>::value_type,
2649
+ typename basic_fbstring<E, T, A, S>::traits_type>& is,
2650
+ basic_fbstring<E, T, A, S>& str) {
2651
+ typedef std::basic_istream<
2652
+ typename basic_fbstring<E, T, A, S>::value_type,
2653
+ typename basic_fbstring<E, T, A, S>::traits_type>
2654
+ _istream_type;
2655
+ typename _istream_type::sentry sentry(is);
2656
+ size_t extracted = 0;
2657
+ typename _istream_type::iostate err = _istream_type::goodbit;
2658
+ if (sentry) {
2659
+ auto n = is.width();
2660
+ if (n <= 0) {
2661
+ n = str.max_size();
2662
+ }
2663
+ str.erase();
2664
+ for (auto got = is.rdbuf()->sgetc(); extracted != size_t(n); ++extracted) {
2665
+ if (got == T::eof()) {
2666
+ err |= _istream_type::eofbit;
2667
+ is.width(0);
2668
+ break;
2669
+ }
2670
+ if (isspace(got)) {
2671
+ break;
2672
+ }
2673
+ str.push_back(got);
2674
+ got = is.rdbuf()->snextc();
2675
+ }
2676
+ }
2677
+ if (!extracted) {
2678
+ err |= _istream_type::failbit;
2679
+ }
2680
+ if (err) {
2681
+ is.setstate(err);
2682
+ }
2683
+ return is;
2684
+ }
2685
+
2686
+ template <typename E, class T, class A, class S>
2687
+ inline std::basic_ostream<
2688
+ typename basic_fbstring<E, T, A, S>::value_type,
2689
+ typename basic_fbstring<E, T, A, S>::traits_type>&
2690
+ operator<<(
2691
+ std::basic_ostream<
2692
+ typename basic_fbstring<E, T, A, S>::value_type,
2693
+ typename basic_fbstring<E, T, A, S>::traits_type>& os,
2694
+ const basic_fbstring<E, T, A, S>& str) {
2695
+ #ifdef _LIBCPP_VERSION
2696
+ typedef std::basic_ostream<
2697
+ typename basic_fbstring<E, T, A, S>::value_type,
2698
+ typename basic_fbstring<E, T, A, S>::traits_type>
2699
+ _ostream_type;
2700
+ typename _ostream_type::sentry _s(os);
2701
+ if (_s) {
2702
+ typedef std::ostreambuf_iterator<
2703
+ typename basic_fbstring<E, T, A, S>::value_type,
2704
+ typename basic_fbstring<E, T, A, S>::traits_type>
2705
+ _Ip;
2706
+ size_t __len = str.size();
2707
+ bool __left =
2708
+ (os.flags() & _ostream_type::adjustfield) == _ostream_type::left;
2709
+ if (__pad_and_output(
2710
+ _Ip(os),
2711
+ str.data(),
2712
+ __left ? str.data() + __len : str.data(),
2713
+ str.data() + __len,
2714
+ os,
2715
+ os.fill())
2716
+ .failed()) {
2717
+ os.setstate(_ostream_type::badbit | _ostream_type::failbit);
2718
+ }
2719
+ }
2720
+ #elif defined(_MSC_VER)
2721
+ typedef decltype(os.precision()) streamsize;
2722
+ // MSVC doesn't define __ostream_insert
2723
+ os.write(str.data(), static_cast<streamsize>(str.size()));
2724
+ #else
2725
+ std::__ostream_insert(os, str.data(), str.size());
2726
+ #endif
2727
+ return os;
2728
+ }
2729
+
2730
+ // basic_string compatibility routines
2731
+
2732
+ template <typename E, class T, class A, class S, class A2>
2733
+ inline bool operator==(
2734
+ const basic_fbstring<E, T, A, S>& lhs,
2735
+ const std::basic_string<E, T, A2>& rhs) {
2736
+ return lhs.compare(0, lhs.size(), rhs.data(), rhs.size()) == 0;
2737
+ }
2738
+
2739
+ template <typename E, class T, class A, class S, class A2>
2740
+ inline bool operator==(
2741
+ const std::basic_string<E, T, A2>& lhs,
2742
+ const basic_fbstring<E, T, A, S>& rhs) {
2743
+ return rhs == lhs;
2744
+ }
2745
+
2746
+ template <typename E, class T, class A, class S, class A2>
2747
+ inline bool operator!=(
2748
+ const basic_fbstring<E, T, A, S>& lhs,
2749
+ const std::basic_string<E, T, A2>& rhs) {
2750
+ return !(lhs == rhs);
2751
+ }
2752
+
2753
+ template <typename E, class T, class A, class S, class A2>
2754
+ inline bool operator!=(
2755
+ const std::basic_string<E, T, A2>& lhs,
2756
+ const basic_fbstring<E, T, A, S>& rhs) {
2757
+ return !(lhs == rhs);
2758
+ }
2759
+
2760
+ template <typename E, class T, class A, class S, class A2>
2761
+ inline bool operator<(
2762
+ const basic_fbstring<E, T, A, S>& lhs,
2763
+ const std::basic_string<E, T, A2>& rhs) {
2764
+ return lhs.compare(0, lhs.size(), rhs.data(), rhs.size()) < 0;
2765
+ }
2766
+
2767
+ template <typename E, class T, class A, class S, class A2>
2768
+ inline bool operator>(
2769
+ const basic_fbstring<E, T, A, S>& lhs,
2770
+ const std::basic_string<E, T, A2>& rhs) {
2771
+ return lhs.compare(0, lhs.size(), rhs.data(), rhs.size()) > 0;
2772
+ }
2773
+
2774
+ template <typename E, class T, class A, class S, class A2>
2775
+ inline bool operator<(
2776
+ const std::basic_string<E, T, A2>& lhs,
2777
+ const basic_fbstring<E, T, A, S>& rhs) {
2778
+ return rhs > lhs;
2779
+ }
2780
+
2781
+ template <typename E, class T, class A, class S, class A2>
2782
+ inline bool operator>(
2783
+ const std::basic_string<E, T, A2>& lhs,
2784
+ const basic_fbstring<E, T, A, S>& rhs) {
2785
+ return rhs < lhs;
2786
+ }
2787
+
2788
+ template <typename E, class T, class A, class S, class A2>
2789
+ inline bool operator<=(
2790
+ const basic_fbstring<E, T, A, S>& lhs,
2791
+ const std::basic_string<E, T, A2>& rhs) {
2792
+ return !(lhs > rhs);
2793
+ }
2794
+
2795
+ template <typename E, class T, class A, class S, class A2>
2796
+ inline bool operator>=(
2797
+ const basic_fbstring<E, T, A, S>& lhs,
2798
+ const std::basic_string<E, T, A2>& rhs) {
2799
+ return !(lhs < rhs);
2800
+ }
2801
+
2802
+ template <typename E, class T, class A, class S, class A2>
2803
+ inline bool operator<=(
2804
+ const std::basic_string<E, T, A2>& lhs,
2805
+ const basic_fbstring<E, T, A, S>& rhs) {
2806
+ return !(lhs > rhs);
2807
+ }
2808
+
2809
+ template <typename E, class T, class A, class S, class A2>
2810
+ inline bool operator>=(
2811
+ const std::basic_string<E, T, A2>& lhs,
2812
+ const basic_fbstring<E, T, A, S>& rhs) {
2813
+ return !(lhs < rhs);
2814
+ }
2815
+
2816
+ typedef basic_fbstring<char> fbstring;
2817
+
2818
+ // fbstring is relocatable
2819
+ template <class T, class R, class A, class S>
2820
+ FOLLY_ASSUME_RELOCATABLE(basic_fbstring<T, R, A, S>);
2821
+
2822
+ // Compatibility function, to make sure toStdString(s) can be called
2823
+ // to convert a std::string or fbstring variable s into type std::string
2824
+ // with very little overhead if s was already std::string
2825
+ inline std::string toStdString(const folly::fbstring& s) {
2826
+ return std::string(s.data(), s.size());
2827
+ }
2828
+
2829
+ inline const std::string& toStdString(const std::string& s) {
2830
+ return s;
2831
+ }
2832
+
2833
+ // If called with a temporary, the compiler will select this overload instead
2834
+ // of the above, so we don't return a (lvalue) reference to a temporary.
2835
+ inline std::string&& toStdString(std::string&& s) {
2836
+ return std::move(s);
2837
+ }
2838
+
2839
+ } // namespace folly
2840
+
2841
+ // Hash functions to make fbstring usable with e.g. unordered_map
2842
+
2843
+ #define FOLLY_FBSTRING_HASH1(T) \
2844
+ template <> \
2845
+ struct hash<::folly::basic_fbstring<T>> { \
2846
+ size_t operator()(const ::folly::basic_fbstring<T>& s) const { \
2847
+ return ::folly::hash::fnv32_buf(s.data(), s.size() * sizeof(T)); \
2848
+ } \
2849
+ };
2850
+
2851
+ // The C++11 standard says that these four are defined for basic_string
2852
+ #define FOLLY_FBSTRING_HASH \
2853
+ FOLLY_FBSTRING_HASH1(char) \
2854
+ FOLLY_FBSTRING_HASH1(char16_t) \
2855
+ FOLLY_FBSTRING_HASH1(char32_t) \
2856
+ FOLLY_FBSTRING_HASH1(wchar_t)
2857
+
2858
+ namespace std {
2859
+
2860
+ FOLLY_FBSTRING_HASH
2861
+
2862
+ } // namespace std
2863
+
2864
+ #undef FOLLY_FBSTRING_HASH
2865
+ #undef FOLLY_FBSTRING_HASH1
2866
+
2867
+ FOLLY_POP_WARNING
2868
+
2869
+ #undef FBSTRING_DISABLE_SSO
2870
+
2871
+ namespace folly {
2872
+ template <class T>
2873
+ struct IsSomeString;
2874
+
2875
+ template <>
2876
+ struct IsSomeString<fbstring> : std::true_type {};
2877
+ } // namespace folly
2878
+
2879
+ template <>
2880
+ struct fmt::formatter<folly::fbstring> : private formatter<fmt::string_view> {
2881
+ using formatter<fmt::string_view>::parse;
2882
+
2883
+ template <typename Context>
2884
+ typename Context::iterator format(
2885
+ const folly::fbstring& s, Context& ctx) const {
2886
+ return formatter<fmt::string_view>::format({s.data(), s.size()}, ctx);
2887
+ }
2888
+ };