passenger 6.1.0 → 6.1.1

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 (440) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +32 -2
  3. data/Rakefile +6 -13
  4. data/bin/passenger-install-apache2-module +15 -19
  5. data/bin/passenger-install-nginx-module +42 -44
  6. data/bin/passenger-status +9 -10
  7. data/build/common_library.rb +4 -4
  8. data/build/support/vendor/cxxcodebuilder/lib/cxxcodebuilder/builder.rb +1 -1
  9. data/build/test_basics.rb +4 -3
  10. data/dev/copy_boost_headers +54 -40
  11. data/dev/ruby_server.rb +1 -1
  12. data/src/agent/Core/Config.h +1 -1
  13. data/src/agent/Core/Controller/Config.h +1 -1
  14. data/src/agent/Watchdog/Config.h +1 -1
  15. data/src/cxx_supportlib/Constants.h +1 -1
  16. data/src/cxx_supportlib/vendor-modified/boost/assert/source_location.hpp +8 -1
  17. data/src/cxx_supportlib/vendor-modified/boost/assert.hpp +6 -0
  18. data/src/cxx_supportlib/vendor-modified/boost/atomic/atomic.hpp +94 -110
  19. data/src/cxx_supportlib/vendor-modified/boost/atomic/atomic_flag.hpp +2 -2
  20. data/src/cxx_supportlib/vendor-modified/boost/atomic/atomic_ref.hpp +14 -14
  21. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/addressof.hpp +3 -3
  22. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_flag_impl.hpp +52 -24
  23. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_impl.hpp +641 -285
  24. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_ref_impl.hpp +593 -260
  25. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/bitwise_cast.hpp +37 -24
  26. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/bitwise_fp_cast.hpp +9 -9
  27. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/cas_based_exchange.hpp +3 -3
  28. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/chrono.hpp +93 -0
  29. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/classify.hpp +16 -17
  30. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/config.hpp +25 -34
  31. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_aarch32.hpp +204 -97
  32. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_aarch64.hpp +251 -122
  33. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_alpha.hpp +56 -56
  34. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_arm.hpp +129 -129
  35. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_ppc.hpp +253 -125
  36. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_sparc.hpp +25 -25
  37. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_x86.hpp +193 -126
  38. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_msvc_arm.hpp +57 -57
  39. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_msvc_x86.hpp +96 -97
  40. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_operations_emulated.hpp +24 -24
  41. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_ops_cas_based.hpp +10 -10
  42. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_ops_gcc_atomic.hpp +27 -24
  43. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_ops_gcc_sync.hpp +39 -37
  44. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_ops_linux_arm.hpp +17 -17
  45. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extending_cas_based_arithmetic.hpp +5 -5
  46. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_fp_ops_emulated.hpp +12 -12
  47. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_fp_ops_generic.hpp +21 -21
  48. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_emulated.hpp +30 -30
  49. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_gcc_aarch32.hpp +170 -98
  50. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_gcc_aarch64.hpp +209 -119
  51. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_gcc_arm.hpp +95 -95
  52. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_gcc_ppc.hpp +148 -76
  53. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_gcc_x86.hpp +293 -123
  54. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_generic.hpp +87 -71
  55. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_msvc_arm.hpp +5 -5
  56. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_msvc_x86.hpp +88 -88
  57. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_operations.hpp +2 -2
  58. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_aarch32.hpp +4 -5
  59. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_aarch64.hpp +4 -4
  60. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_alpha.hpp +4 -4
  61. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_arm.hpp +9 -9
  62. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_ppc.hpp +4 -4
  63. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_sparc.hpp +4 -4
  64. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_gcc_x86.hpp +4 -4
  65. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_msvc_arm.hpp +5 -5
  66. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_arch_ops_msvc_x86.hpp +6 -6
  67. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_operations.hpp +2 -2
  68. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_operations_emulated.hpp +2 -2
  69. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_ops_gcc_atomic.hpp +5 -5
  70. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_ops_gcc_sync.hpp +4 -4
  71. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fence_ops_linux_arm.hpp +7 -7
  72. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fp_ops_emulated.hpp +7 -7
  73. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/fp_ops_generic.hpp +6 -6
  74. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/futex.hpp +110 -49
  75. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/gcc_atomic_memory_order_utils.hpp +1 -1
  76. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/has_posix_clock_traits.hpp +51 -0
  77. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/int_sizes.hpp +26 -32
  78. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/integral_conversions.hpp +15 -15
  79. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/interlocked.hpp +69 -30
  80. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/intptr.hpp +8 -8
  81. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/lock_pool.hpp +51 -31
  82. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/memory_order_utils.hpp +2 -2
  83. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/once_flag.hpp +2 -2
  84. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_arm_common.hpp +6 -6
  85. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_ppc_common.hpp +4 -4
  86. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/platform.hpp +5 -5
  87. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/storage_traits.hpp +31 -31
  88. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/alignment_of.hpp +2 -3
  89. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/has_unique_object_representations.hpp +2 -5
  90. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_floating_point.hpp +3 -3
  91. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_iec559.hpp +2 -2
  92. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_integral.hpp +3 -3
  93. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_signed.hpp +3 -3
  94. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_trivially_copyable.hpp +20 -13
  95. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp +13 -13
  96. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/make_signed.hpp +3 -3
  97. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/make_unsigned.hpp +3 -3
  98. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_darwin_ulock.hpp +90 -16
  99. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_dragonfly_umtx.hpp +80 -11
  100. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_emulated.hpp +160 -15
  101. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_freebsd_umtx.hpp +327 -38
  102. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_futex.hpp +276 -33
  103. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_generic.hpp +260 -20
  104. data/src/cxx_supportlib/vendor-modified/boost/atomic/fences.hpp +4 -3
  105. data/src/cxx_supportlib/vendor-modified/boost/atomic/ipc_atomic.hpp +14 -18
  106. data/src/cxx_supportlib/vendor-modified/boost/atomic/ipc_atomic_flag.hpp +2 -2
  107. data/src/cxx_supportlib/vendor-modified/boost/atomic/ipc_atomic_ref.hpp +13 -13
  108. data/src/cxx_supportlib/vendor-modified/boost/atomic/posix_clock_traits_fwd.hpp +59 -0
  109. data/src/cxx_supportlib/vendor-modified/boost/atomic/thread_pause.hpp +102 -0
  110. data/src/cxx_supportlib/vendor-modified/boost/atomic/wait_result.hpp +56 -0
  111. data/src/cxx_supportlib/vendor-modified/boost/atomic.hpp +4 -1
  112. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcpp.hpp +5 -0
  113. data/src/cxx_supportlib/vendor-modified/boost/container/allocator.hpp +1 -1
  114. data/src/cxx_supportlib/vendor-modified/boost/container/allocator_traits.hpp +108 -41
  115. data/src/cxx_supportlib/vendor-modified/boost/container/deque.hpp +1235 -1009
  116. data/src/cxx_supportlib/vendor-modified/boost/container/detail/advanced_insert_int.hpp +3 -2
  117. data/src/cxx_supportlib/vendor-modified/boost/container/detail/algorithm.hpp +56 -0
  118. data/src/cxx_supportlib/vendor-modified/boost/container/detail/alloc_helpers.hpp +1 -0
  119. data/src/cxx_supportlib/vendor-modified/boost/container/detail/alloc_lib.h +9 -9
  120. data/src/cxx_supportlib/vendor-modified/boost/container/detail/compare_functors.hpp +23 -2
  121. data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_begin.hpp +0 -1
  122. data/src/cxx_supportlib/vendor-modified/boost/container/detail/copy_move_algo.hpp +88 -23
  123. data/src/cxx_supportlib/vendor-modified/boost/container/detail/flat_tree.hpp +2 -1
  124. data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_pool_impl.hpp +2 -2
  125. data/src/cxx_supportlib/vendor-modified/boost/container/detail/operator_new_helpers.hpp +68 -0
  126. data/src/cxx_supportlib/vendor-modified/boost/container/detail/pair.hpp +72 -13
  127. data/src/cxx_supportlib/vendor-modified/boost/container/detail/std_fwd.hpp +13 -0
  128. data/src/cxx_supportlib/vendor-modified/boost/container/detail/tree.hpp +8 -5
  129. data/src/cxx_supportlib/vendor-modified/boost/container/devector.hpp +31 -10
  130. data/src/cxx_supportlib/vendor-modified/boost/container/flat_map.hpp +37 -10
  131. data/src/cxx_supportlib/vendor-modified/boost/container/flat_set.hpp +19 -0
  132. data/src/cxx_supportlib/vendor-modified/boost/container/list.hpp +23 -1
  133. data/src/cxx_supportlib/vendor-modified/boost/container/map.hpp +72 -5
  134. data/src/cxx_supportlib/vendor-modified/boost/container/new_allocator.hpp +3 -10
  135. data/src/cxx_supportlib/vendor-modified/boost/container/options.hpp +54 -23
  136. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/devector.hpp +6 -4
  137. data/src/cxx_supportlib/vendor-modified/boost/container/set.hpp +19 -0
  138. data/src/cxx_supportlib/vendor-modified/boost/container/slist.hpp +32 -5
  139. data/src/cxx_supportlib/vendor-modified/boost/container/small_vector.hpp +27 -2
  140. data/src/cxx_supportlib/vendor-modified/boost/container/stable_vector.hpp +22 -0
  141. data/src/cxx_supportlib/vendor-modified/boost/container/static_vector.hpp +37 -17
  142. data/src/cxx_supportlib/vendor-modified/boost/container/string.hpp +23 -1
  143. data/src/cxx_supportlib/vendor-modified/boost/container/vector.hpp +41 -20
  144. data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash.hpp +5 -8
  145. data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash_fwd.hpp +3 -1
  146. data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash_is_avalanching.hpp +57 -0
  147. data/src/cxx_supportlib/vendor-modified/boost/core/bit.hpp +29 -29
  148. data/src/cxx_supportlib/vendor-modified/boost/core/cmath.hpp +3 -3
  149. data/src/cxx_supportlib/vendor-modified/boost/core/data.hpp +15 -1
  150. data/src/cxx_supportlib/vendor-modified/boost/core/default_allocator.hpp +1 -0
  151. data/src/cxx_supportlib/vendor-modified/boost/core/demangle.hpp +1 -1
  152. data/src/cxx_supportlib/vendor-modified/boost/core/detail/assert.hpp +18 -0
  153. data/src/cxx_supportlib/vendor-modified/boost/core/detail/sp_thread_sleep.hpp +2 -2
  154. data/src/cxx_supportlib/vendor-modified/boost/core/detail/static_assert.hpp +42 -0
  155. data/src/cxx_supportlib/vendor-modified/boost/core/detail/string_view.hpp +16 -10
  156. data/src/cxx_supportlib/vendor-modified/boost/core/lightweight_test.hpp +35 -27
  157. data/src/cxx_supportlib/vendor-modified/boost/core/scoped_enum.hpp +1 -1
  158. data/src/cxx_supportlib/vendor-modified/boost/core/size.hpp +14 -0
  159. data/src/cxx_supportlib/vendor-modified/boost/core/span.hpp +20 -9
  160. data/src/cxx_supportlib/vendor-modified/boost/cregex.hpp +0 -5
  161. data/src/cxx_supportlib/vendor-modified/boost/describe/detail/config.hpp +8 -0
  162. data/src/cxx_supportlib/vendor-modified/boost/describe/modifiers.hpp +1 -1
  163. data/src/cxx_supportlib/vendor-modified/boost/foreach.hpp +1 -0
  164. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/ebo_functor_holder.hpp +4 -4
  165. data/src/cxx_supportlib/vendor-modified/boost/intrusive/list.hpp +2 -2
  166. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pointer_rebind.hpp +9 -0
  167. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree_algorithms.hpp +1 -0
  168. data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist.hpp +2 -2
  169. data/src/cxx_supportlib/vendor-modified/boost/iterator/advance.hpp +43 -64
  170. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/config_def.hpp +0 -83
  171. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/config_undef.hpp +1 -5
  172. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/eval_if_default.hpp +44 -0
  173. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/facade_iterator_category.hpp +103 -117
  174. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/type_traits/conjunction.hpp +53 -0
  175. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/type_traits/disjunction.hpp +53 -0
  176. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/type_traits/negation.hpp +53 -0
  177. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/type_traits/type_identity.hpp +54 -0
  178. data/src/cxx_supportlib/vendor-modified/boost/iterator/distance.hpp +32 -38
  179. data/src/cxx_supportlib/vendor-modified/boost/iterator/enable_if_convertible.hpp +84 -0
  180. data/src/cxx_supportlib/vendor-modified/boost/iterator/interoperable.hpp +22 -34
  181. data/src/cxx_supportlib/vendor-modified/boost/iterator/is_iterator.hpp +16 -16
  182. data/src/cxx_supportlib/vendor-modified/boost/iterator/iterator_adaptor.hpp +162 -309
  183. data/src/cxx_supportlib/vendor-modified/boost/iterator/iterator_categories.hpp +52 -161
  184. data/src/cxx_supportlib/vendor-modified/boost/iterator/iterator_concepts.hpp +3 -11
  185. data/src/cxx_supportlib/vendor-modified/boost/iterator/iterator_facade.hpp +804 -977
  186. data/src/cxx_supportlib/vendor-modified/boost/iterator/iterator_traits.hpp +24 -17
  187. data/src/cxx_supportlib/vendor-modified/boost/iterator/min_category.hpp +83 -0
  188. data/src/cxx_supportlib/vendor-modified/boost/iterator/minimum_category.hpp +11 -73
  189. data/src/cxx_supportlib/vendor-modified/boost/iterator/reverse_iterator.hpp +56 -57
  190. data/src/cxx_supportlib/vendor-modified/boost/iterator/transform_iterator.hpp +123 -156
  191. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/bad_lexical_cast.hpp +1 -1
  192. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/buffer_view.hpp +1 -1
  193. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical.hpp +36 -33
  194. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical_streams.hpp +43 -50
  195. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_numeric.hpp +23 -27
  196. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/inf_nan.hpp +1 -1
  197. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/is_character.hpp +10 -11
  198. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_basic_unlockedbuf.hpp +1 -1
  199. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_char_constants.hpp +1 -1
  200. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_unsigned_converters.hpp +6 -7
  201. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/type_traits.hpp +81 -0
  202. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/widest_char.hpp +4 -4
  203. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/try_lexical_convert.hpp +8 -9
  204. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast.hpp +1 -1
  205. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/wide_posix_api.cpp +1 -12
  206. data/src/cxx_supportlib/vendor-modified/boost/memory_order.hpp +8 -26
  207. data/src/cxx_supportlib/vendor-modified/boost/move/detail/iterator_to_raw_pointer.hpp +1 -1
  208. data/src/cxx_supportlib/vendor-modified/boost/move/detail/launder.hpp +1 -1
  209. data/src/cxx_supportlib/vendor-modified/boost/move/detail/std_ns_begin.hpp +6 -0
  210. data/src/cxx_supportlib/vendor-modified/boost/move/detail/unique_ptr_meta_utils.hpp +2 -2
  211. data/src/cxx_supportlib/vendor-modified/boost/mp11/algorithm.hpp +11 -44
  212. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_map_find.hpp +34 -0
  213. data/src/cxx_supportlib/vendor-modified/boost/mp11/set.hpp +33 -1
  214. data/src/cxx_supportlib/vendor-modified/boost/mp11/version.hpp +1 -1
  215. data/src/cxx_supportlib/vendor-modified/boost/mpl/and.hpp +4 -8
  216. data/src/cxx_supportlib/vendor-modified/boost/mpl/aux_/na_assert.hpp +1 -1
  217. data/src/cxx_supportlib/vendor-modified/boost/mpl/aux_/ptr_to_ref.hpp +1 -1
  218. data/src/cxx_supportlib/vendor-modified/boost/mpl/bitand.hpp +2 -6
  219. data/src/cxx_supportlib/vendor-modified/boost/mpl/bitor.hpp +2 -6
  220. data/src/cxx_supportlib/vendor-modified/boost/mpl/or.hpp +2 -6
  221. data/src/cxx_supportlib/vendor-modified/boost/pool/pool.hpp +1 -1
  222. data/src/cxx_supportlib/vendor-modified/boost/pool/simple_segregated_storage.hpp +0 -13
  223. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/tuple/limits/to_seq_256.hpp +190 -190
  224. data/src/cxx_supportlib/vendor-modified/boost/random/beta_distribution.hpp +12 -2
  225. data/src/cxx_supportlib/vendor-modified/boost/random/detail/config.hpp +4 -0
  226. data/src/cxx_supportlib/vendor-modified/boost/random/detail/size.hpp +41 -0
  227. data/src/cxx_supportlib/vendor-modified/boost/random/detail/xoshiro_base.hpp +472 -0
  228. data/src/cxx_supportlib/vendor-modified/boost/random/discrete_distribution.hpp +7 -10
  229. data/src/cxx_supportlib/vendor-modified/boost/random/gamma_distribution.hpp +1 -1
  230. data/src/cxx_supportlib/vendor-modified/boost/random/generalized_inverse_gaussian_distribution.hpp +339 -0
  231. data/src/cxx_supportlib/vendor-modified/boost/random/hyperexponential_distribution.hpp +12 -14
  232. data/src/cxx_supportlib/vendor-modified/boost/random/inverse_gaussian_distribution.hpp +226 -0
  233. data/src/cxx_supportlib/vendor-modified/boost/random/mersenne_twister.hpp +1 -4
  234. data/src/cxx_supportlib/vendor-modified/boost/random/mixmax.hpp +63 -63
  235. data/src/cxx_supportlib/vendor-modified/boost/random/piecewise_constant_distribution.hpp +7 -10
  236. data/src/cxx_supportlib/vendor-modified/boost/random/piecewise_linear_distribution.hpp +8 -11
  237. data/src/cxx_supportlib/vendor-modified/boost/random/seed_seq.hpp +1 -3
  238. data/src/cxx_supportlib/vendor-modified/boost/random/splitmix64.hpp +1 -4
  239. data/src/cxx_supportlib/vendor-modified/boost/random/xoshiro.hpp +488 -0
  240. data/src/cxx_supportlib/vendor-modified/boost/random.hpp +3 -0
  241. data/src/cxx_supportlib/vendor-modified/boost/range/concepts.hpp +2 -0
  242. data/src/cxx_supportlib/vendor-modified/boost/range/detail/has_member_size.hpp +1 -0
  243. data/src/cxx_supportlib/vendor-modified/boost/range/detail/msvc_has_iterator_workaround.hpp +2 -0
  244. data/src/cxx_supportlib/vendor-modified/boost/range/has_range_iterator.hpp +1 -1
  245. data/src/cxx_supportlib/vendor-modified/boost/range/iterator.hpp +1 -0
  246. data/src/cxx_supportlib/vendor-modified/boost/range/iterator_range_core.hpp +4 -1
  247. data/src/cxx_supportlib/vendor-modified/boost/range/size_type.hpp +1 -1
  248. data/src/cxx_supportlib/vendor-modified/boost/regex/concepts.hpp +35 -18
  249. data/src/cxx_supportlib/vendor-modified/boost/regex/config.hpp +18 -101
  250. data/src/cxx_supportlib/vendor-modified/boost/regex/pattern_except.hpp +0 -4
  251. data/src/cxx_supportlib/vendor-modified/boost/regex/pending/object_cache.hpp +0 -4
  252. data/src/cxx_supportlib/vendor-modified/boost/regex/pending/unicode_iterator.hpp +0 -6
  253. data/src/cxx_supportlib/vendor-modified/boost/regex/regex_traits.hpp +0 -4
  254. data/src/cxx_supportlib/vendor-modified/boost/regex/user.hpp +4 -10
  255. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/basic_regex.hpp +63 -17
  256. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/basic_regex_creator.hpp +71 -16
  257. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/basic_regex_parser.hpp +22 -1
  258. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/c_regex_traits.hpp +11 -4
  259. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/char_regex_traits.hpp +2 -0
  260. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/cpp_regex_traits.hpp +11 -8
  261. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/cregex.hpp +2 -1
  262. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/error_type.hpp +1 -1
  263. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/icu.hpp +40 -38
  264. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/iterator_category.hpp +2 -0
  265. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/iterator_traits.hpp +4 -0
  266. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/match_flags.hpp +39 -37
  267. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/match_results.hpp +46 -9
  268. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/mem_block_cache.hpp +4 -0
  269. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/object_cache.hpp +2 -0
  270. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/pattern_except.hpp +6 -4
  271. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/perl_matcher.hpp +57 -8
  272. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/perl_matcher_common.hpp +21 -6
  273. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/perl_matcher_non_recursive.hpp +18 -3
  274. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regbase.hpp +4 -2
  275. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex.hpp +6 -6
  276. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_format.hpp +23 -18
  277. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_fwd.hpp +9 -9
  278. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_grep.hpp +9 -5
  279. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_iterator.hpp +11 -7
  280. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_match.hpp +10 -7
  281. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_merge.hpp +4 -4
  282. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_raw_buffer.hpp +3 -0
  283. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_replace.hpp +6 -2
  284. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_search.hpp +12 -9
  285. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_split.hpp +6 -3
  286. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_token_iterator.hpp +16 -11
  287. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_traits.hpp +1 -1
  288. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_traits_defaults.hpp +2 -0
  289. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/regex_workaround.hpp +2 -0
  290. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/states.hpp +7 -0
  291. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/sub_match.hpp +54 -49
  292. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/syntax_type.hpp +64 -62
  293. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/u32regex_iterator.hpp +16 -0
  294. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/u32regex_token_iterator.hpp +12 -0
  295. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/unicode_iterator.hpp +6 -4
  296. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/w32_regex_traits.hpp +3 -1
  297. data/src/cxx_supportlib/vendor-modified/boost/regex.hpp +0 -4
  298. data/src/cxx_supportlib/vendor-modified/boost/regex_fwd.hpp +0 -4
  299. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count.hpp +1 -43
  300. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/deprecated_macros.hpp +7 -7
  301. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/shared_count.hpp +2 -77
  302. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base.hpp +1 -64
  303. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_nt.hpp +3 -3
  304. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_impl.hpp +0 -77
  305. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp +37 -0
  306. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock.hpp +5 -28
  307. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/intrusive_ptr.hpp +41 -40
  308. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_array.hpp +0 -15
  309. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_ptr.hpp +0 -18
  310. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_ptr.hpp +1 -1
  311. data/src/cxx_supportlib/vendor-modified/boost/thread/future.hpp +1 -1
  312. data/src/cxx_supportlib/vendor-modified/boost/tuple/detail/tuple_basic.hpp +1 -0
  313. data/src/cxx_supportlib/vendor-modified/boost/type_traits/integral_constant.hpp +8 -6
  314. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_complete.hpp +31 -10
  315. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/fca.hpp +34 -8
  316. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/foa/core.hpp +6 -4
  317. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/foa/table.hpp +9 -1
  318. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/implementation.hpp +5 -5
  319. data/src/cxx_supportlib/vendor-modified/boost/unordered/{unordered_printers.hpp → detail/unordered_printers.hpp} +34 -36
  320. data/src/cxx_supportlib/vendor-modified/boost/unordered/hash_traits.hpp +6 -49
  321. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_map.hpp +6 -1
  322. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_set.hpp +6 -1
  323. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_node_map.hpp +6 -1
  324. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_node_set.hpp +6 -1
  325. data/src/cxx_supportlib/vendor-modified/boost/version.hpp +2 -2
  326. data/src/nginx_module/ContentHandler.c +2 -0
  327. data/src/ruby_supportlib/phusion_passenger/config/download_agent_command.rb +3 -5
  328. data/src/ruby_supportlib/phusion_passenger/config/download_nginx_engine_command.rb +3 -5
  329. data/src/ruby_supportlib/phusion_passenger/config/install_agent_command.rb +3 -5
  330. data/src/ruby_supportlib/phusion_passenger/config/install_standalone_runtime_command.rb +3 -5
  331. data/src/ruby_supportlib/phusion_passenger/config/installation_utils.rb +1 -1
  332. data/src/ruby_supportlib/phusion_passenger/config/nginx_engine_compiler.rb +2 -2
  333. data/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb +5 -3
  334. data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +2 -2
  335. data/src/ruby_supportlib/phusion_passenger/platform_info/compiler.rb +6 -13
  336. data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +29 -30
  337. data/src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb +2 -3
  338. data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +2 -0
  339. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +1 -1
  340. data/src/ruby_supportlib/phusion_passenger/utils/json.rb +1 -1
  341. data/src/ruby_supportlib/phusion_passenger/utils/terminal_choice_menu.rb +1 -1
  342. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +1 -1
  343. data/src/ruby_supportlib/phusion_passenger.rb +8 -8
  344. metadata +26 -99
  345. data/src/cxx_supportlib/vendor-modified/boost/align/aligned_alloc.hpp +0 -47
  346. data/src/cxx_supportlib/vendor-modified/boost/align/detail/aligned_alloc_posix.hpp +0 -41
  347. data/src/cxx_supportlib/vendor-modified/boost/align/detail/aligned_alloc_sunos.hpp +0 -34
  348. data/src/cxx_supportlib/vendor-modified/boost/align/detail/is_alignment.hpp +0 -28
  349. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/pause.hpp +0 -68
  350. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/conditional.hpp +0 -42
  351. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/integral_constant.hpp +0 -46
  352. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_enum.hpp +0 -42
  353. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_function.hpp +0 -42
  354. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_nothrow_default_constructible.hpp +0 -46
  355. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/remove_cv.hpp +0 -42
  356. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_on_address.hpp +0 -64
  357. data/src/cxx_supportlib/vendor-modified/boost/cerrno.hpp +0 -15
  358. data/src/cxx_supportlib/vendor-modified/boost/detail/indirect_traits.hpp +0 -195
  359. data/src/cxx_supportlib/vendor-modified/boost/detail/select_type.hpp +0 -36
  360. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/enable_if.hpp +0 -83
  361. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/internals.hpp +0 -35
  362. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex.cpp +0 -120
  363. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex_debug.cpp +0 -59
  364. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/static_mutex.cpp +0 -189
  365. data/src/cxx_supportlib/vendor-modified/boost/libs/system/src/error_code.cpp +0 -31
  366. data/src/cxx_supportlib/vendor-modified/boost/regex/config/borland.hpp +0 -72
  367. data/src/cxx_supportlib/vendor-modified/boost/regex/config/cwchar.hpp +0 -207
  368. data/src/cxx_supportlib/vendor-modified/boost/regex/pending/static_mutex.hpp +0 -182
  369. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex.hpp +0 -797
  370. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_creator.hpp +0 -1598
  371. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_parser.hpp +0 -3174
  372. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/c_regex_traits.hpp +0 -511
  373. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/char_regex_traits.hpp +0 -81
  374. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/cpp_regex_traits.hpp +0 -1237
  375. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/cregex.hpp +0 -213
  376. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/error_type.hpp +0 -59
  377. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/icu.hpp +0 -1516
  378. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/indexed_bit_flag.hpp +0 -54
  379. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/iterator_category.hpp +0 -91
  380. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/iterator_traits.hpp +0 -135
  381. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/match_flags.hpp +0 -161
  382. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/match_results.hpp +0 -716
  383. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/mem_block_cache.hpp +0 -183
  384. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/object_cache.hpp +0 -171
  385. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/pattern_except.hpp +0 -128
  386. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher.hpp +0 -645
  387. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_common.hpp +0 -1030
  388. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_non_recursive.hpp +0 -1947
  389. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_recursive.hpp +0 -1131
  390. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/primary_transform.hpp +0 -146
  391. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/protected_call.hpp +0 -83
  392. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regbase.hpp +0 -180
  393. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex.hpp +0 -166
  394. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_format.hpp +0 -1158
  395. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_fwd.hpp +0 -73
  396. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_grep.hpp +0 -155
  397. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_iterator.hpp +0 -195
  398. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_match.hpp +0 -382
  399. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_merge.hpp +0 -93
  400. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_raw_buffer.hpp +0 -241
  401. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_replace.hpp +0 -99
  402. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_search.hpp +0 -217
  403. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_split.hpp +0 -174
  404. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_token_iterator.hpp +0 -327
  405. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_traits.hpp +0 -189
  406. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_traits_defaults.hpp +0 -997
  407. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_workaround.hpp +0 -237
  408. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/states.hpp +0 -321
  409. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/sub_match.hpp +0 -516
  410. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/syntax_type.hpp +0 -105
  411. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/u32regex_iterator.hpp +0 -185
  412. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/u32regex_token_iterator.hpp +0 -360
  413. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/unicode_iterator.hpp +0 -871
  414. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/w32_regex_traits.hpp +0 -1229
  415. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count_gcc.hpp +0 -79
  416. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp +0 -63
  417. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp +0 -88
  418. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count_pt.hpp +0 -104
  419. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count_spin.hpp +0 -69
  420. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count_sync.hpp +0 -72
  421. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +0 -163
  422. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_aix.hpp +0 -152
  423. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +0 -185
  424. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp +0 -148
  425. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +0 -170
  426. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +0 -200
  427. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +0 -194
  428. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +0 -179
  429. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +0 -186
  430. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_pt.hpp +0 -147
  431. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +0 -174
  432. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_spin.hpp +0 -141
  433. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_sync.hpp +0 -165
  434. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +0 -163
  435. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp +0 -30
  436. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp +0 -69
  437. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +0 -128
  438. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock_nt.hpp +0 -96
  439. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock_pt.hpp +0 -86
  440. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock_sync.hpp +0 -94
@@ -1,6 +1,6 @@
1
1
  //////////////////////////////////////////////////////////////////////////////
2
2
  //
3
- // (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost
3
+ // (C) Copyright Ion Gaztanaga 2025-2025. Distributed under the Boost
4
4
  // Software License, Version 1.0. (See accompanying file
5
5
  // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
6
  //
@@ -38,8 +38,10 @@
38
38
  #include <boost/container/detail/mpl.hpp>
39
39
  #include <boost/move/detail/to_raw_pointer.hpp>
40
40
  #include <boost/container/detail/type_traits.hpp>
41
+ #include <boost/container/detail/math_functions.hpp>
41
42
  // move
42
43
  #include <boost/move/adl_move_swap.hpp>
44
+ #include <boost/move/algo/detail/merge.hpp>
43
45
  #include <boost/move/iterator.hpp>
44
46
  #include <boost/move/traits.hpp>
45
47
  #include <boost/move/utility_core.hpp>
@@ -61,8 +63,6 @@ namespace boost {
61
63
  namespace container {
62
64
 
63
65
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
64
- template <class T, class Allocator, class Options>
65
- class deque;
66
66
 
67
67
  template <class T>
68
68
  struct deque_value_traits
@@ -72,468 +72,56 @@ struct deque_value_traits
72
72
  BOOST_STATIC_CONSTEXPR bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
73
73
  };
74
74
 
75
- template<class T, std::size_t BlockBytes, std::size_t BlockSize>
76
- struct deque_block_size
75
+ template<class T, std::size_t BlockBytes, std::size_t BlockSize, class StoredSizeType>
76
+ struct deque_block_traits
77
77
  {
78
78
  BOOST_CONTAINER_STATIC_ASSERT_MSG(!(BlockBytes && BlockSize), "BlockBytes and BlockSize can't be specified at the same time");
79
- BOOST_STATIC_CONSTEXPR std::size_t block_bytes = BlockBytes ? BlockBytes : 512u;
80
- BOOST_STATIC_CONSTEXPR std::size_t value = BlockSize ? BlockSize : (sizeof(T) < block_bytes ? (block_bytes/sizeof(T)) : std::size_t(1));
81
- };
82
-
83
- namespace dtl {
84
-
85
- // Class invariants:
86
- // For any nonsingular iterator i:
87
- // i.node is the address of an element in the map array. The
88
- // contents of i.node is a pointer to the beginning of a node.
89
- // i.first == //(i.node)
90
- // i.last == i.first + node_size
91
- // i.cur is a pointer in the range [i.first, i.last). NOTE:
92
- // the implication of this is that i.cur is always a dereferenceable
93
- // pointer, even if i is a past-the-end iterator.
94
- // Start and Finish are always nonsingular iterators. NOTE: this means
95
- // that an empty deque must have one node, and that a deque
96
- // with N elements, where N is the buffer size, must have two nodes.
97
- // For every node other than start.node and finish.node, every element
98
- // in the node is an initialized object. If start.node == finish.node,
99
- // then [start.cur, finish.cur) are initialized objects, and
100
- // the elements outside that range are uninitialized storage. Otherwise,
101
- // [start.cur, start.last) and [finish.first, finish.cur) are initialized
102
- // objects, and [start.first, start.cur) and [finish.cur, finish.last)
103
- // are uninitialized storage.
104
- // [map, map + map_size) is a valid, non-empty range.
105
- // [start.node, finish.node] is a valid range contained within
106
- // [map, map + map_size).
107
- // A pointer in the range [map, map + map_size) points to an allocated node
108
- // if and only if the pointer is in the range [start.node, finish.node].
109
-
110
- #define BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL 0
111
-
112
- #if BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 0
113
- template<class Pointer, bool IsConst>
114
- class deque_iterator
115
- {
116
- public:
117
- typedef std::random_access_iterator_tag iterator_category;
118
- typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
119
- typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
120
- typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
121
- typedef typename if_c
122
- < IsConst
123
- , typename boost::intrusive::pointer_traits<Pointer>::template
124
- rebind_pointer<const value_type>::type
125
- , Pointer
126
- >::type pointer;
127
- typedef typename if_c
128
- < IsConst
129
- , const value_type&
130
- , value_type&
131
- >::type reference;
132
-
133
- class nat;
134
- typedef typename dtl::if_c< IsConst
135
- , deque_iterator<Pointer, false>
136
- , nat>::type nonconst_iterator;
137
-
138
- typedef Pointer val_alloc_ptr;
139
- typedef typename boost::intrusive::pointer_traits<Pointer>::
140
- template rebind_pointer<Pointer>::type index_pointer;
141
-
142
- Pointer m_cur;
143
- Pointer m_first;
144
- Pointer m_last;
145
- index_pointer m_node;
146
-
147
- public:
148
-
149
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
150
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return m_first; }
151
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return m_last; }
152
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
153
-
154
- inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
155
- : m_cur(x), m_first(*y), m_last(*y + block_size), m_node(y)
156
- {}
157
-
158
- inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
159
- : m_cur(x), m_first(*y), m_last(*y + difference_type(block_size)), m_node(y)
160
- {}
161
-
162
- inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
163
- : m_cur(), m_first(), m_last(), m_node() //Value initialization to achieve "null iterators" (N3644)
164
- {}
165
-
166
- inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
167
- : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
168
- {}
169
-
170
- inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
171
- : m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
172
- {}
173
-
174
- inline deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
175
- : m_cur(cur), m_first(first), m_last(last), m_node(node)
176
- {}
177
-
178
- inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
179
- { m_cur = x.get_cur(); m_first = x.get_first(); m_last = x.get_last(); m_node = x.get_node(); return *this; }
180
-
181
- inline deque_iterator<Pointer, false> unconst() const BOOST_NOEXCEPT_OR_NOTHROW
182
- {
183
- return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
184
- }
185
-
186
- inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
187
- { return *this->m_cur; }
188
-
189
- inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
190
- { return this->m_cur; }
191
-
192
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
193
- {
194
- if(!this->m_cur && !x.m_cur){
195
- return 0;
196
- }
197
- const difference_type block_size = m_last - m_first;
198
- BOOST_ASSERT(block_size);
199
- return block_size * (this->m_node - x.m_node - 1) +
200
- (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
201
- }
202
-
203
- deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
204
- {
205
- BOOST_ASSERT(!!m_cur);
206
- ++this->m_cur;
207
- if (this->m_cur == this->m_last) {
208
- const difference_type block_size = m_last - m_first;
209
- BOOST_ASSERT(block_size);
210
- this->priv_set_node(this->m_node + 1, block_size);
211
- this->m_cur = this->m_first;
212
- }
213
- return *this;
214
- }
215
-
216
- inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
217
- {
218
- deque_iterator tmp(*this);
219
- ++*this;
220
- return tmp;
221
- }
222
-
223
- deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
224
- {
225
- BOOST_ASSERT(!!m_cur);
226
- if (this->m_cur == this->m_first) {
227
- const difference_type block_size = m_last - m_first;
228
- BOOST_ASSERT(block_size);
229
- this->priv_set_node(this->m_node - 1, block_size);
230
- this->m_cur = this->m_last;
231
- }
232
- --this->m_cur;
233
- return *this;
234
- }
79
+ //Calculate default block size
80
+ BOOST_STATIC_CONSTEXPR std::size_t default_block_bytes = sizeof(void*)*128u;
81
+ BOOST_STATIC_CONSTEXPR std::size_t default_block_start = (default_block_bytes - 1u)/sizeof(T) + 1u;
82
+ //Round to the next power of two
83
+ BOOST_STATIC_CONSTEXPR std::size_t default_block_size_upp_pow2 = dtl::upper_power_of_2_ct<std::size_t, default_block_start>::value;
84
+
85
+ //Check minimal size
86
+ BOOST_STATIC_CONSTEXPR std::size_t default_min_block_size_pow = 3u;
87
+ BOOST_STATIC_CONSTEXPR std::size_t default_min_block_size = 8u;
88
+ BOOST_STATIC_CONSTEXPR std::size_t default_block_size_initial = default_block_size_upp_pow2 < default_min_block_size
89
+ ? default_min_block_size
90
+ : default_block_size_upp_pow2;
91
+
92
+ //Limit by stored size max value
93
+ BOOST_STATIC_CONSTEXPR std::size_t max_stored_size_block_size = std::size_t(1u) << (sizeof(StoredSizeType)*CHAR_BIT - default_min_block_size_pow);
94
+ BOOST_STATIC_CONSTEXPR std::size_t default_block_size = default_block_size_initial > max_stored_size_block_size
95
+ ? max_stored_size_block_size
96
+ : default_block_size_initial;
97
+ //Now select between the default or the specified by the user
98
+ BOOST_STATIC_CONSTEXPR std::size_t value = BlockSize ? BlockSize
99
+ : BlockBytes ? (BlockBytes-1u)/sizeof(T) + 1u : default_block_size
100
+ ;
101
+ BOOST_CONTAINER_STATIC_ASSERT_MSG(value <= max_stored_size_block_size, "BlockSize or BlockBytes is too big for the stored_size_type");
235
102
 
236
- inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
237
- {
238
- deque_iterator tmp(*this);
239
- --*this;
240
- return tmp;
241
- }
242
-
243
- deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
244
- {
245
- if (!n)
246
- return *this;
247
- BOOST_ASSERT(!!m_cur);
248
- const difference_type offset = n + (this->m_cur - this->m_first);
249
- const difference_type block_size = m_last - m_first;
250
- BOOST_ASSERT(block_size);
251
- if (offset >= 0 && offset < block_size)
252
- this->m_cur += difference_type(n);
253
- else {
254
- const difference_type node_offset =
255
- offset > 0 ? (offset / block_size)
256
- : (-difference_type((-offset - 1) / block_size) - 1);
257
- this->priv_set_node(this->m_node + node_offset, size_type(block_size));
258
- this->m_cur = this->m_first +
259
- (offset - node_offset * block_size);
260
- }
261
- return *this;
262
- }
263
-
264
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
265
- deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
266
- { deque_iterator tmp(*this); return tmp += n; }
267
-
268
- inline
269
- deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
270
- { return *this += -n; }
271
-
272
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
273
- deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
274
- { deque_iterator tmp(*this); return tmp -= n; }
275
-
276
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
277
- reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
278
- { return *(*this + n); }
279
-
280
- //Comparisons
281
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
282
- friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
283
- { return l.m_cur == r.m_cur; }
284
-
285
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
286
- friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
287
- { return l.m_cur != r.m_cur; }
288
-
289
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
290
- friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
291
- { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
292
-
293
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
294
- friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
295
- { return r < l; }
296
-
297
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
298
- friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
299
- { return !(r < l); }
300
-
301
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
302
- friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
303
- { return !(l < r); }
304
-
305
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
306
- friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
307
- { return x += n; }
308
-
309
- inline void priv_set_node(index_pointer new_node, size_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
310
- { return this->priv_set_node(new_node, difference_type(block_size)); }
311
-
312
- inline void priv_set_node(index_pointer new_node, difference_type block_size) BOOST_NOEXCEPT_OR_NOTHROW
313
- {
314
- this->m_node = new_node;
315
- this->m_first = *new_node;
316
- this->m_last = this->m_first + block_size;
317
- }
318
103
  };
319
104
 
320
- #elif BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 1
321
-
322
- template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize>
323
- class deque_iterator
324
- {
325
- public:
326
- typedef std::random_access_iterator_tag iterator_category;
327
- typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
328
- typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
329
- typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
330
- typedef typename if_c
331
- < IsConst
332
- , typename boost::intrusive::pointer_traits<Pointer>::template
333
- rebind_pointer<const value_type>::type
334
- , Pointer
335
- >::type pointer;
336
- typedef typename if_c
337
- < IsConst
338
- , const value_type&
339
- , value_type&
340
- >::type reference;
341
-
342
- BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
343
- { return deque_block_size<value_type, BlockBytes, BlockSize>::value; }
344
-
345
- BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
346
- { return difference_type((get_block_size())); }
347
-
348
- class nat;
349
- typedef typename dtl::if_c< IsConst
350
- , deque_iterator<Pointer, false, BlockBytes, BlockSize>
351
- , nat>::type nonconst_iterator;
352
-
353
- typedef Pointer val_alloc_ptr;
354
- typedef typename boost::intrusive::pointer_traits<Pointer>::
355
- template rebind_pointer<Pointer>::type index_pointer;
356
-
357
- Pointer m_cur;
358
- Pointer m_first;
359
- index_pointer m_node;
360
-
361
- public:
362
-
363
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
364
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return m_first; }
365
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return m_first + get_block_ssize(); }
366
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
367
-
368
- inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type ) BOOST_NOEXCEPT_OR_NOTHROW
369
- : m_cur(x), m_first(*y), m_node(y)
370
- {}
371
-
372
- inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
373
- : m_cur(x), m_first(*y), m_node(y)
374
- {}
375
-
376
- inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
377
- : m_cur(), m_first(), m_node() //Value initialization to achieve "null iterators" (N3644)
378
- {}
379
-
380
- inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
381
- : m_cur(x.get_cur()), m_first(x.get_first()), m_node(x.get_node())
382
- {}
383
-
384
- inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
385
- : m_cur(x.get_cur()), m_first(x.get_first()), m_node(x.get_node())
386
- {}
387
-
388
- inline deque_iterator(Pointer cur, Pointer first, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
389
- : m_cur(cur), m_first(first), m_node(node)
390
- {}
391
-
392
- inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
393
- { m_cur = x.get_cur(); m_first = x.get_first(); m_node = x.get_node(); return *this; }
394
-
395
- inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
396
- {
397
- return nonconst_iterator(this->get_cur(), this->get_first(), this->get_node());
398
- }
399
-
400
- inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
401
- { return *this->m_cur; }
402
-
403
- inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
404
- { return this->m_cur; }
405
-
406
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
407
- {
408
- if(!this->m_cur && !x.m_cur){
409
- return 0;
410
- }
411
- const difference_type block_size = get_block_ssize();
412
- BOOST_ASSERT(block_size);
413
- return block_size * (this->m_node - x.m_node - 1) +
414
- (this->m_cur - this->m_first) + ((x.m_first+block_size) - x.m_cur);
415
- }
416
-
417
- deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
418
- {
419
- BOOST_ASSERT(!!m_cur);
420
- ++this->m_cur;
421
- const difference_type block_size = get_block_ssize();
422
- if (this->m_cur == (this->m_first+block_size)) {
423
-
424
- BOOST_ASSERT(block_size);
425
- ++this->m_node;
426
- this->m_first = *this->m_node;
427
- this->m_cur = this->m_first;
428
- }
429
- return *this;
430
- }
431
-
432
- inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
433
- {
434
- deque_iterator tmp(*this);
435
- ++*this;
436
- return tmp;
437
- }
438
-
439
- deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
440
- {
441
- BOOST_ASSERT(!!m_cur);
442
- if (this->m_cur == this->m_first) {
443
- --this->m_node;
444
- this->m_first = *this->m_node;
445
- this->m_cur = this->m_first + get_block_ssize();
446
- }
447
- --this->m_cur;
448
- return *this;
449
- }
450
-
451
- inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
452
- {
453
- deque_iterator tmp(*this);
454
- --*this;
455
- return tmp;
456
- }
457
-
458
- deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
459
- {
460
- if (!n)
461
- return *this;
462
- BOOST_ASSERT(!!m_cur);
463
- const difference_type offset = n + (this->m_cur - this->m_first);
464
- const difference_type block_size = get_block_ssize();
465
- BOOST_ASSERT(block_size);
466
- if (offset >= 0 && offset < block_size)
467
- this->m_cur += difference_type(n);
468
- else {
469
- const difference_type node_offset =
470
- offset > 0 ? (offset / block_size)
471
- : (-difference_type((-offset - 1) / block_size) - 1);
472
- this->m_node += node_offset;
473
- this->m_first = *this->m_node;
474
- this->m_cur = this->m_first + (offset - node_offset * block_size);
475
- }
476
- return *this;
477
- }
478
-
479
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
480
- deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
481
- { deque_iterator tmp(*this); return tmp += n; }
482
-
483
- inline
484
- deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
485
- { return *this += -n; }
486
-
487
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
488
- deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
489
- { deque_iterator tmp(*this); return tmp -= n; }
490
-
491
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
492
- reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
493
- { return *(*this + n); }
494
-
495
- //Comparisons
496
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
497
- friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
498
- { return l.m_cur == r.m_cur; }
499
-
500
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
501
- friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
502
- { return l.m_cur != r.m_cur; }
503
-
504
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
505
- friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
506
- { return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
507
-
508
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
509
- friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
510
- { return r < l; }
511
-
512
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
513
- friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
514
- { return !(r < l); }
515
-
516
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
517
- friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
518
- { return !(l < r); }
519
-
520
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
521
- friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
522
- { return x += n; }
523
-
524
- inline void priv_set_node(index_pointer new_node, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
525
- { return this->priv_set_node(new_node, difference_type()); }
526
-
527
- inline void priv_set_node(index_pointer new_node, difference_type) BOOST_NOEXCEPT_OR_NOTHROW
528
- {
529
- this->m_node = new_node;
530
- this->m_first = *new_node;
531
- }
532
- };
533
-
534
- #elif BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 2
535
-
536
- template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize>
105
+ // Class invariants:
106
+ // For any nonsingular iterator i:
107
+ // i.node is the address of an element in the map array. The
108
+ // contents of i.node is a pointer to the beginning of a node.
109
+ // i.cur is a pointer in the range [i.first, i.last). NOTE:
110
+ // the implication of this is that i.cur is always a dereferenceable
111
+ // pointer, even if i is a past-the-end iterator.
112
+ // For every node other than start.node and finish.node, every element
113
+ // in the node is an initialized object. If start.node == finish.node,
114
+ // then [start.cur, finish.cur) are initialized objects, and
115
+ // the elements outside that range are uninitialized storage. Otherwise,
116
+ // [start.cur, start.last) and [finish.first, finish.cur) are initialized
117
+ // objects, and [start.first, start.cur) and [finish.cur, finish.last)
118
+ // are uninitialized storage.
119
+ // [map, map + map_size) is a valid range.
120
+ // [start.node, finish.node] is a valid range contained within
121
+ // [map, map + map_size).
122
+ // A pointer in the range [map, map + map_size) points to an allocated node
123
+ // if and only if the pointer is in the range [start.node, finish.node].
124
+ template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize, class StoredSizeType>
537
125
  class deque_iterator
538
126
  {
539
127
  public:
@@ -541,13 +129,13 @@ class deque_iterator
541
129
  typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
542
130
  typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
543
131
  typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
544
- typedef typename if_c
132
+ typedef typename dtl::if_c
545
133
  < IsConst
546
134
  , typename boost::intrusive::pointer_traits<Pointer>::template
547
135
  rebind_pointer<const value_type>::type
548
136
  , Pointer
549
137
  >::type pointer;
550
- typedef typename if_c
138
+ typedef typename dtl::if_c
551
139
  < IsConst
552
140
  , const value_type&
553
141
  , value_type&
@@ -555,37 +143,40 @@ class deque_iterator
555
143
 
556
144
  BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
557
145
  {
558
- BOOST_CONTAINER_STATIC_ASSERT((deque_block_size<value_type, BlockBytes, BlockSize>::value));
559
- return deque_block_size<value_type, BlockBytes, BlockSize>::value;
146
+ return deque_block_traits<value_type, BlockBytes, BlockSize, StoredSizeType>::value;
560
147
  }
561
148
 
562
149
  BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
563
150
  { return difference_type((get_block_size())); }
564
151
 
565
- class nat;
566
- typedef typename dtl::if_c< IsConst
567
- , deque_iterator<Pointer, false, BlockBytes, BlockSize>
568
- , nat>::type nonconst_iterator;
569
-
570
152
  typedef Pointer val_alloc_ptr;
571
153
  typedef typename boost::intrusive::pointer_traits<Pointer>::
572
154
  template rebind_pointer<Pointer>::type index_pointer;
573
155
 
156
+ class nat
157
+ {
158
+ public:
159
+ inline Pointer get_cur() const { return Pointer(); }
160
+ inline index_pointer get_node() const { return index_pointer(); }
161
+ };
162
+
163
+ typedef typename dtl::if_c< IsConst
164
+ , deque_iterator<Pointer, false, BlockBytes, BlockSize, StoredSizeType>
165
+ , nat>::type nonconst_iterator_arg;
166
+
167
+ typedef deque_iterator<Pointer, false, BlockBytes, BlockSize, StoredSizeType> nonconst_iterator;
168
+
574
169
  Pointer m_cur;
575
170
  index_pointer m_node;
576
171
 
577
172
  public:
578
173
 
579
174
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
580
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return *m_node; }
581
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return *m_node + get_block_ssize(); }
582
175
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
176
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return *m_node; }
177
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return *m_node + get_block_ssize(); }
583
178
 
584
- inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type ) BOOST_NOEXCEPT_OR_NOTHROW
585
- : m_cur(x), m_node(y)
586
- {}
587
-
588
- inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
179
+ inline deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_NOEXCEPT_OR_NOTHROW
589
180
  : m_cur(x), m_node(y)
590
181
  {}
591
182
 
@@ -597,17 +188,16 @@ class deque_iterator
597
188
  : m_cur(x.get_cur()), m_node(x.get_node())
598
189
  {}
599
190
 
600
- inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
191
+ inline deque_iterator(const nonconst_iterator_arg& x) BOOST_NOEXCEPT_OR_NOTHROW
601
192
  : m_cur(x.get_cur()), m_node(x.get_node())
602
193
  {}
603
194
 
604
- inline deque_iterator(Pointer cur, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
605
- : m_cur(cur), m_node(node)
606
- {}
607
-
608
195
  inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
609
196
  { m_cur = x.get_cur(); m_node = x.get_node(); return *this; }
610
197
 
198
+ inline deque_iterator& operator=(const nonconst_iterator_arg& x) BOOST_NOEXCEPT_OR_NOTHROW
199
+ { m_cur = x.get_cur(); m_node = x.get_node(); return *this; }
200
+
611
201
  inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
612
202
  {
613
203
  return nonconst_iterator(this->get_cur(), this->get_node());
@@ -621,21 +211,20 @@ class deque_iterator
621
211
 
622
212
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
623
213
  {
624
- if(!this->m_cur && !x.m_cur){
214
+ if(this->m_cur == x.m_cur){ //Includes when both are null
625
215
  return 0;
626
216
  }
627
- const difference_type block_size = get_block_ssize();
628
- BOOST_ASSERT(block_size);
629
- return block_size * (this->m_node - x.m_node - 1) +
630
- (this->m_cur - this->get_first()) + (x.get_last() - x.m_cur);
217
+ BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
218
+ return block_size * (this->m_node - x.m_node) +
219
+ (this->m_cur - this->get_first()) - (x.m_cur - x.get_first());
631
220
  }
632
221
 
633
222
  deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
634
223
  {
635
224
  BOOST_ASSERT(!!m_cur);
636
225
  ++this->m_cur;
637
- if (this->m_cur == (this->get_last())) {
638
-
226
+ const Pointer last = *m_node + get_block_ssize();
227
+ if (BOOST_UNLIKELY(this->m_cur == last)) {
639
228
  ++this->m_node;
640
229
  this->m_cur = *this->m_node;
641
230
  }
@@ -649,17 +238,30 @@ class deque_iterator
649
238
  return tmp;
650
239
  }
651
240
 
241
+ //Some GCC versions issue bogus warnings about array bounds here
242
+ #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
243
+ # pragma GCC diagnostic ignored "-Warray-bounds"
244
+ #endif
245
+
652
246
  deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
653
247
  {
654
248
  BOOST_ASSERT(!!m_cur);
655
- if (this->m_cur == this->get_first()) {
249
+ const Pointer first = *m_node;
250
+ if (BOOST_UNLIKELY(this->m_cur == first)) {
656
251
  --this->m_node;
657
- this->m_cur = this->get_last();
252
+ this->m_cur = *this->m_node;
253
+ this->m_cur += get_block_ssize() - 1;
254
+ }
255
+ else {
256
+ --this->m_cur;
658
257
  }
659
- --this->m_cur;
660
258
  return *this;
661
259
  }
662
260
 
261
+ #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
262
+ #pragma GCC diagnostic pop
263
+ #endif
264
+
663
265
  inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
664
266
  {
665
267
  deque_iterator tmp(*this);
@@ -669,20 +271,20 @@ class deque_iterator
669
271
 
670
272
  deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
671
273
  {
672
- if (!n)
673
- return *this;
674
- BOOST_ASSERT(!!m_cur);
675
- const difference_type offset = n + (this->m_cur - this->get_first());
676
- const difference_type block_size = get_block_ssize();
677
- BOOST_ASSERT(block_size);
678
- if (offset >= 0 && offset < block_size)
679
- this->m_cur += difference_type(n);
680
- else {
681
- const difference_type node_offset =
682
- offset > 0 ? (offset / block_size)
683
- : (-difference_type((-offset - 1) / block_size) - 1);
684
- this->m_node += node_offset;
685
- this->m_cur = this->get_first() + (offset - node_offset * block_size);
274
+ if (n){
275
+ BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
276
+
277
+ const difference_type offset = n + (this->m_cur - *this->m_node);
278
+
279
+ if (offset >= 0 && offset < block_size)
280
+ this->m_cur += difference_type(n);
281
+ else {
282
+ const difference_type node_offset =
283
+ offset > 0 ? (offset / block_size)
284
+ : (-difference_type((-offset - 1) / block_size) - 1);
285
+ this->m_node += node_offset;
286
+ this->m_cur = *this->m_node + difference_type(offset - node_offset * block_size);
287
+ }
686
288
  }
687
289
  return *this;
688
290
  }
@@ -703,8 +305,10 @@ class deque_iterator
703
305
  reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
704
306
  {
705
307
  BOOST_ASSERT(!!m_cur);
706
- const difference_type offset = n + (this->m_cur - this->get_first());
707
- const difference_type block_size = get_block_ssize();
308
+ BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
309
+
310
+ const difference_type offset = n + (this->m_cur - *this->m_node);
311
+
708
312
  if (offset >= 0 && offset < block_size)
709
313
  return this->m_cur[difference_type(n)];
710
314
  else {
@@ -744,34 +348,26 @@ class deque_iterator
744
348
  friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
745
349
  { return x += n; }
746
350
 
747
- inline void priv_set_node(index_pointer new_node, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
748
- { return this->priv_set_node(new_node, difference_type()); }
749
-
750
- inline void priv_set_node(index_pointer new_node, difference_type) BOOST_NOEXCEPT_OR_NOTHROW
751
- {
752
- this->m_node = new_node;
753
- }
351
+ inline void priv_set_node(index_pointer new_node) BOOST_NOEXCEPT_OR_NOTHROW
352
+ { this->m_node = new_node; }
754
353
  };
755
354
 
756
- #else
757
-
758
- #error "Invalid BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL"
759
-
760
- #endif
761
- } //namespace dtl {
762
355
 
763
- template<class Options>
356
+ template<class Options, class AllocatorSizeType>
764
357
  struct get_deque_opt
765
358
  {
766
- typedef Options type;
359
+ typedef deque_opt< Options::block_bytes, Options::block_size
360
+ , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
361
+ , Options::reservable> type;
767
362
  };
768
363
 
769
- template<>
770
- struct get_deque_opt<void>
364
+ template<class AllocatorSizeType>
365
+ struct get_deque_opt<void, AllocatorSizeType>
771
366
  {
772
- typedef deque_null_opt type;
367
+ typedef deque_opt<deque_null_opt::block_bytes, deque_null_opt::block_size, AllocatorSizeType, deque_null_opt::reservable> type;
773
368
  };
774
369
 
370
+
775
371
  // Deque base class. It has two purposes. First, its constructor
776
372
  // and destructor allocate (but don't initialize) storage. This makes
777
373
  // exception safety easier.
@@ -796,47 +392,59 @@ class deque_base
796
392
  typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
797
393
  typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
798
394
  typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
799
- typedef Allocator allocator_type;
395
+ typedef Allocator allocator_type;
800
396
  typedef allocator_type stored_allocator_type;
801
397
  typedef val_alloc_size size_type;
802
398
  typedef val_alloc_diff difference_type;
803
399
 
804
400
  private:
805
- typedef typename get_deque_opt<Options>::type options_type;
401
+ typedef typename get_deque_opt<Options, val_alloc_size>::type options_type;
806
402
 
807
403
  protected:
808
- #if BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 0
809
- typedef dtl::deque_iterator<val_alloc_ptr, false> iterator;
810
- typedef dtl::deque_iterator<val_alloc_ptr, true> const_iterator;
811
- #else
812
- typedef dtl::deque_iterator<val_alloc_ptr, false, options_type::block_bytes, options_type::block_size> iterator;
813
- typedef dtl::deque_iterator<val_alloc_ptr, true, options_type::block_bytes, options_type::block_size> const_iterator;
814
- #endif
404
+ typedef typename options_type::stored_size_type stored_size_type;
405
+ typedef deque_iterator< val_alloc_ptr, false
406
+ , options_type::block_bytes
407
+ , options_type::block_size
408
+ , stored_size_type> iterator;
409
+ typedef deque_iterator< val_alloc_ptr, true
410
+ , options_type::block_bytes
411
+ , options_type::block_size
412
+ , stored_size_type> const_iterator;
413
+
414
+ static const bool is_reservable = options_type::reservable;
815
415
 
816
416
  BOOST_CONSTEXPR inline static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
817
417
  { return val_alloc_diff((get_block_size())); }
818
418
 
819
419
  BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
820
- { return deque_block_size<val_alloc_val, options_type::block_bytes, options_type::block_size>::value; }
420
+ { return deque_block_traits<val_alloc_val, options_type::block_bytes, options_type::block_size, stored_size_type>::value; }
821
421
 
822
422
  typedef deque_value_traits<val_alloc_val> traits_t;
823
423
  typedef ptr_alloc_t map_allocator_type;
824
424
 
825
- inline val_alloc_ptr priv_allocate_node()
826
- { return this->alloc().allocate(get_block_size()); }
425
+ inline val_alloc_ptr prot_allocate_node()
426
+ {
427
+ return this->alloc().allocate(get_block_size());
428
+ }
827
429
 
828
- inline void priv_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
829
- { this->alloc().deallocate(p, get_block_size()); }
430
+ inline void prot_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
431
+ {
432
+ this->alloc().deallocate(p, get_block_size());
433
+ }
830
434
 
831
- inline ptr_alloc_ptr priv_allocate_map(size_type n)
832
- { return this->ptr_alloc().allocate(n); }
435
+ inline ptr_alloc_ptr prot_allocate_map(size_type n)
436
+ {
437
+ return this->ptr_alloc().allocate(n);
438
+ }
833
439
 
834
- inline void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
835
- { this->ptr_alloc().deallocate(p, n); }
440
+ inline void prot_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
441
+ {
442
+ this->ptr_alloc().deallocate(p, n);
443
+ }
836
444
 
837
445
  inline deque_base(size_type num_elements, const allocator_type& a)
838
446
  : members_(a)
839
- { this->priv_initialize_map(num_elements); }
447
+ { this->prot_initialize_map_and_nodes(num_elements); }
840
448
 
841
449
  inline explicit deque_base(const allocator_type& a)
842
450
  : members_(a)
@@ -854,8 +462,8 @@ class deque_base
854
462
  ~deque_base()
855
463
  {
856
464
  if (this->members_.m_map) {
857
- this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
858
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
465
+ this->prot_deallocate_all_nodes();
466
+ this->prot_deallocate_map(this->members_.m_map, this->members_.m_map_size);
859
467
  }
860
468
  }
861
469
 
@@ -866,117 +474,542 @@ class deque_base
866
474
 
867
475
  void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW
868
476
  {
869
- ::boost::adl_move_swap(this->members_.m_start, x.members_.m_start);
870
- ::boost::adl_move_swap(this->members_.m_finish, x.members_.m_finish);
871
- ::boost::adl_move_swap(this->members_.m_map, x.members_.m_map);
872
- ::boost::adl_move_swap(this->members_.m_map_size, x.members_.m_map_size);
477
+ this->members_.swap(x.members_);
478
+ }
479
+
480
+ void test_size_against_max(size_type n)
481
+ {
482
+ const size_type max_alloc = val_alloc_traits_type::max_size(this->alloc());
483
+ const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1);
484
+ if (BOOST_UNLIKELY(max < n) )
485
+ boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
486
+ }
487
+
488
+ void test_size_against_n_nodes(size_type n_nodes)
489
+ {
490
+ test_size_against_max(size_type(size_type(n_nodes * get_block_size()) - 1u));
491
+ }
492
+
493
+ void prot_initialize_map_and_nodes(size_type num_elements)
494
+ {
495
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
496
+ //Even a zero element initialized map+nodes needs at least 1 node (for sentinel finish position)
497
+ size_type num_nodes = size_type(num_elements / block_size + 1u);
498
+
499
+ //Allocate at least one extra slot on each end to avoid inmediate map reallocation on push/front insertions
500
+ const size_type map_size = dtl::max_value(size_type(InitialMapSize), size_type(num_nodes + 2u));
501
+ const size_type start_map_pos = size_type(map_size - num_nodes)/2u;
502
+
503
+ //The end position must be representable in stored_size_type
504
+ this->test_size_against_n_nodes(map_size);
505
+
506
+ this->members_.m_map = this->prot_allocate_map(map_size);
507
+ this->members_.m_map_size = static_cast<stored_size_type>(map_size);
508
+
509
+
510
+ BOOST_CONTAINER_TRY {
511
+ BOOST_IF_CONSTEXPR(is_reservable){ //reservable implies all slots are allocated with nodes
512
+ this->prot_allocate_nodes(this->members_.m_map, map_size);
513
+ }
514
+ else{ //Otherwise only create the nodes that will hold values
515
+ this->prot_allocate_nodes(this->members_.m_map + difference_type(start_map_pos), num_nodes);
516
+ }
517
+ }
518
+ BOOST_CONTAINER_CATCH(...){
519
+ this->prot_deallocate_map(this->members_.m_map, this->members_.m_map_size);
520
+ this->members_.m_map = ptr_alloc_ptr();
521
+ this->members_.m_map_size = 0;
522
+ BOOST_CONTAINER_RETHROW
523
+ }
524
+ BOOST_CONTAINER_CATCH_END
525
+
526
+ this->prot_set_start_finish_from_node(start_map_pos, num_elements);
527
+ }
528
+
529
+ static size_type priv_new_offset(bool add_at_front, size_type map_size, size_type active_nodes, size_type additional_nodes)
530
+ {
531
+ return size_type(size_type(map_size - active_nodes) / 2 + (add_at_front ? +additional_nodes : +0));
873
532
  }
874
533
 
875
- void priv_initialize_map(size_type num_elements)
534
+ void prot_reallocate_map_and_nodes //is_reservable == true
535
+ (dtl::bool_<true>, const size_type new_elems, const bool add_at_front)
876
536
  {
877
- // if(num_elements){
878
- size_type num_nodes = num_elements / get_block_size() + 1;
537
+ const ptr_alloc_ptr start_node = this->prot_start_node();
538
+ const size_type old_active_nodes = size_type(this->prot_finish_node() + 1u - start_node);
539
+
540
+ const size_type additional_nodes = size_type((new_elems - 1u)/get_block_size() + 1u);
541
+ const size_type new_active_nodes = size_type(old_active_nodes + additional_nodes);
879
542
 
880
- this->members_.m_map_size = dtl::max_value((size_type) InitialMapSize, num_nodes + 2);
881
- this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
543
+ ptr_alloc_ptr new_nstart;
544
+ const size_type old_map_size = this->members_.m_map_size;
545
+ const ptr_alloc_ptr old_map = this->members_.m_map;
882
546
 
883
- ptr_alloc_ptr nstart = this->members_.m_map + difference_type(this->members_.m_map_size - num_nodes) / 2;
884
- ptr_alloc_ptr nfinish = nstart + difference_type(num_nodes);
547
+ //Check for 1.5 factor
548
+ if (old_map_size/3u >= new_active_nodes/2u) {
549
+ new_nstart = old_map + difference_type(priv_new_offset(add_at_front, old_map_size, new_active_nodes, additional_nodes));
550
+ const ptr_alloc_ptr end_node = start_node + difference_type(old_active_nodes);
551
+ if (new_nstart < start_node)
552
+ boost::movelib::rotate_gcd(new_nstart, start_node, end_node);
553
+ else
554
+ boost::movelib::rotate_gcd(start_node, end_node, new_nstart + old_active_nodes);
555
+ }
556
+ else {
557
+ //1.5 increase, but at least one spare slot on each end
558
+ const size_type new_map_size = dtl::max_value(size_type(old_map_size + old_map_size/2u), size_type(new_active_nodes + 2u));
559
+
560
+ //The end position must be representable in stored_size_type
561
+ this->test_size_against_n_nodes(new_map_size);
562
+
563
+ const ptr_alloc_ptr new_map = this->prot_allocate_map(new_map_size);
564
+ const size_type new_active_off = priv_new_offset(add_at_front, new_map_size, new_active_nodes, additional_nodes);
565
+ new_nstart = new_map + difference_type(new_active_off);
566
+
567
+ const size_type new_nodes = size_type(new_map_size - old_map_size);
885
568
 
886
569
  BOOST_CONTAINER_TRY {
887
- this->priv_create_nodes(nstart, nfinish);
570
+ this->prot_allocate_nodes(new_map, new_nodes);
888
571
  }
889
572
  BOOST_CONTAINER_CATCH(...){
890
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
891
- this->members_.m_map = 0;
892
- this->members_.m_map_size = 0;
573
+ this->prot_deallocate_map(new_map, new_map_size);
893
574
  BOOST_CONTAINER_RETHROW
894
575
  }
895
576
  BOOST_CONTAINER_CATCH_END
896
577
 
897
- this->members_.m_start.priv_set_node(nstart, get_block_size());
898
- this->members_.m_finish.priv_set_node(nfinish - 1, get_block_size());
899
- this->members_.m_start.m_cur = this->members_.m_start.get_first();
900
- this->members_.m_finish.m_cur = this->members_.m_finish.get_first() + difference_type(num_elements % get_block_size());
901
- // }
578
+ const ptr_alloc_ptr new_old_node_limit = new_map + difference_type(new_nodes);
579
+
580
+ //Move old nodes from the old map, rotate to the right position and deallocate the old map
581
+ boost::container::move_n(old_map, old_map_size, new_old_node_limit);
582
+
583
+ const size_type old_active_off = size_type(start_node - old_map);
584
+ const ptr_alloc_ptr active_start = new_old_node_limit + difference_type(old_active_off);
585
+ const ptr_alloc_ptr active_end = active_start + difference_type(old_active_nodes);
586
+ if (new_nstart < active_start)
587
+ boost::movelib::rotate_gcd(new_nstart, active_start, active_end);
588
+ else
589
+ boost::movelib::rotate_gcd(active_start, active_end, new_nstart + difference_type(old_active_nodes));
590
+
591
+ this->prot_deallocate_map(old_map, old_map_size);
592
+
593
+ this->members_.m_map = new_map;
594
+ this->members_.m_map_size = static_cast<stored_size_type>(new_map_size);
595
+ }
596
+
597
+ this->prot_start_update_node(new_nstart);
598
+ this->prot_finish_update_node(new_nstart + difference_type(old_active_nodes - 1u));
599
+ }
600
+
601
+ void prot_reallocate_map_and_nodes //is_reservable == false
602
+ (dtl::bool_<false>, const size_type new_elems, const bool add_at_front)
603
+ {
604
+ const size_type additional_nodes = size_type((new_elems - 1u)/get_block_size() + 1u);
605
+
606
+ const ptr_alloc_ptr start_node = this->prot_start_node();
607
+ const ptr_alloc_ptr finish_node = this->prot_finish_node();
608
+
609
+ size_type unused_slots = add_at_front ? size_type(start_node - this->members_.m_map)
610
+ : size_type(this->members_.m_map_size - 1u - size_type(finish_node - this->members_.m_map));
611
+ if (additional_nodes > unused_slots){
612
+ const ptr_alloc_ptr next_finish_node = finish_node + 1u;
613
+ const size_type old_active_nodes = size_type(next_finish_node - start_node);
614
+ const size_type new_active_nodes = size_type(old_active_nodes + additional_nodes);
615
+
616
+ ptr_alloc_ptr new_nstart;
617
+ const size_type old_map_size = this->members_.m_map_size;
618
+ const ptr_alloc_ptr old_map = this->members_.m_map;
619
+
620
+ if (old_map_size/2u >= new_active_nodes) {
621
+ new_nstart = old_map + difference_type(priv_new_offset(add_at_front, old_map_size, new_active_nodes, additional_nodes));
622
+ if (new_nstart < start_node)
623
+ boost::container::move_n(start_node, old_active_nodes, new_nstart);
624
+ else
625
+ boost::container::move_backward_n(next_finish_node, old_active_nodes, new_nstart + difference_type(old_active_nodes));
626
+ }
627
+ else {
628
+ //Doubling size, but at least one spare slot on each end
629
+ const size_type new_map_size = dtl::max_value(size_type(old_map_size*2), size_type(new_active_nodes + 2u));
630
+
631
+ //The end position must be representable in stored_size_type
632
+ this->test_size_against_n_nodes(new_map_size);
633
+
634
+ const ptr_alloc_ptr new_map = this->prot_allocate_map(new_map_size);
635
+
636
+ new_nstart = new_map + difference_type(priv_new_offset(add_at_front, new_map_size, new_active_nodes, additional_nodes));
637
+ boost::container::move_n(start_node, old_active_nodes, new_nstart);
638
+
639
+ this->prot_deallocate_map(old_map, old_map_size);
640
+
641
+ this->members_.m_map = new_map;
642
+ this->members_.m_map_size = static_cast<stored_size_type>(new_map_size);
643
+ }
644
+
645
+ this->prot_start_update_node(new_nstart);
646
+ this->prot_finish_update_node(new_nstart + difference_type(old_active_nodes - 1u));
647
+ }
648
+
649
+ if(add_at_front)
650
+ this->prot_allocate_nodes(this->prot_start_node() - difference_type(additional_nodes), additional_nodes);
651
+ else
652
+ this->prot_allocate_nodes(this->prot_finish_node() + 1, additional_nodes);
902
653
  }
903
654
 
904
- void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
655
+ void prot_allocate_nodes(ptr_alloc_ptr start, size_type n)
905
656
  {
906
- ptr_alloc_ptr cur = nstart;
657
+ size_type i = 0;
907
658
  BOOST_CONTAINER_TRY {
908
- for (; cur < nfinish; ++cur)
909
- *cur = this->priv_allocate_node();
659
+ for (; i < n; ++i)
660
+ start[difference_type(i)] = this->prot_allocate_node();
910
661
  }
911
- BOOST_CONTAINER_CATCH(...){
912
- this->priv_destroy_nodes(nstart, cur);
662
+ BOOST_CONTAINER_CATCH(...) {
663
+ for (size_type j = 0; j < i; ++j)
664
+ this->prot_deallocate_node(start[difference_type(j)]);
913
665
  BOOST_CONTAINER_RETHROW
914
666
  }
915
667
  BOOST_CONTAINER_CATCH_END
916
668
  }
917
669
 
918
- void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
670
+
671
+ void prot_deallocate_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
672
+ {
673
+ for (ptr_alloc_ptr n = nstart; n < nfinish; ++n){
674
+ this->prot_deallocate_node(*n);
675
+ }
676
+ }
677
+
678
+ void prot_deallocate_nodes_if_not_reservable(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
679
+ {
680
+ (void)nstart; (void)nfinish;
681
+ BOOST_IF_CONSTEXPR(!is_reservable)
682
+ this->prot_deallocate_nodes(nstart, nfinish);
683
+ }
684
+
685
+ void prot_deallocate_node_if_not_reservable(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
686
+ {
687
+ (void)p;
688
+ BOOST_IF_CONSTEXPR(!is_reservable)
689
+ this->prot_deallocate_node(p);
690
+ }
691
+
692
+ void prot_deallocate_all_nodes()
919
693
  {
920
- for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
921
- this->priv_deallocate_node(*n);
694
+ BOOST_IF_CONSTEXPR(is_reservable)
695
+ this->prot_deallocate_nodes(this->members_.m_map, this->members_.m_map + difference_type(this->members_.m_map_size));
696
+ else
697
+ this->prot_deallocate_nodes(this->prot_start_node(), this->prot_finish_node() + 1);
922
698
  }
923
699
 
924
- void priv_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
700
+
701
+ void prot_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
925
702
  {
926
703
  if (this->members_.m_map) {
927
- this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
928
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
929
- this->members_.m_map = 0;
930
- this->members_.m_map_size = 0;
931
- this->members_.m_start = iterator();
932
- this->members_.m_finish = this->members_.m_start;
704
+ this->prot_deallocate_all_nodes();
705
+ this->prot_deallocate_map(this->members_.m_map, this->members_.m_map_size);
706
+ this->members_.m_map = ptr_alloc_ptr();
707
+ this->members_.m_map_size = 0u;
708
+ this->members_.m_start_off = 0u;
709
+ this->members_.m_finish_off = 0u;
933
710
  }
934
711
  }
935
712
 
936
- enum { InitialMapSize = 8 };
713
+ enum { InitialMapSize = 4 };
937
714
 
938
715
  protected:
939
716
  struct members_holder
940
717
  : public ptr_alloc_t
941
718
  , public allocator_type
942
719
  {
720
+ friend class deque_base;
943
721
  members_holder()
944
722
  : map_allocator_type(), allocator_type()
945
- , m_map(0), m_map_size(0)
946
- , m_start(), m_finish(m_start)
723
+ , m_map(), m_map_size()
724
+ , m_start_off(), m_finish_off()
947
725
  {}
948
726
 
949
727
  explicit members_holder(const allocator_type &a)
950
728
  : map_allocator_type(a), allocator_type(a)
951
- , m_map(0), m_map_size(0)
952
- , m_start(), m_finish(m_start)
729
+ , m_map(), m_map_size()
730
+ , m_start_off(), m_finish_off()
953
731
  {}
954
732
 
955
733
  template<class ValAllocConvertible, class PtrAllocConvertible>
956
734
  members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
957
735
  : map_allocator_type(boost::forward<PtrAllocConvertible>(pa))
958
736
  , allocator_type (boost::forward<ValAllocConvertible>(va))
959
- , m_map(0), m_map_size(0)
960
- , m_start(), m_finish(m_start)
737
+ , m_map(), m_map_size()
738
+ , m_start_off(), m_finish_off()
961
739
  {}
962
740
 
963
- ptr_alloc_ptr m_map;
964
- val_alloc_size m_map_size;
965
- iterator m_start;
966
- iterator m_finish;
741
+ void swap(members_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
742
+ {
743
+ ::boost::adl_move_swap(this->m_map, x.m_map);
744
+ ::boost::adl_move_swap(this->m_map_size, x.m_map_size);
745
+ ::boost::adl_move_swap(this->m_start_off, x.m_start_off);
746
+ ::boost::adl_move_swap(this->m_finish_off, x.m_finish_off);
747
+ }
748
+
749
+ ptr_alloc_ptr m_map;
750
+ stored_size_type m_map_size;
751
+ private:
752
+ stored_size_type m_start_off;
753
+ stored_size_type m_finish_off;
967
754
  } members_;
968
755
 
969
756
  inline ptr_alloc_t &ptr_alloc() BOOST_NOEXCEPT_OR_NOTHROW
970
757
  { return members_; }
971
758
 
972
- inline const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW
973
- { return members_; }
759
+ inline const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW
760
+ { return members_; }
761
+
762
+ inline allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
763
+ { return members_; }
764
+
765
+ inline const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
766
+ { return members_; }
767
+
768
+ static BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_node_last(ptr_alloc_ptr idx)
769
+ {
770
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
771
+ return *idx + difference_type(block_size - 1u);
772
+ }
773
+
774
+ BOOST_CONTAINER_FORCEINLINE size_type prot_front_free_capacity() const
775
+ {
776
+ BOOST_IF_CONSTEXPR(is_reservable){
777
+ return static_cast<size_type>(this->members_.m_start_off);
778
+ }
779
+ else{
780
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
781
+ return static_cast<size_type>(this->members_.m_start_off % block_size);
782
+ }
783
+ }
784
+
785
+ BOOST_CONTAINER_FORCEINLINE size_type prot_back_free_capacity() const
786
+ {
787
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
788
+
789
+ BOOST_IF_CONSTEXPR(is_reservable){
790
+ return static_cast<size_type>
791
+ (size_type(this->members_.m_map_size*block_size) - size_type(this->members_.m_map != ptr_alloc_ptr()) - this->members_.m_finish_off);
792
+ }
793
+ else {
794
+ //m_finish_off points to positions [0....block_size-1], and one position is always needed as the sentinel node resulting [block_size-1....0] capacity
795
+ return static_cast<size_type>(this->members_.m_map ? (block_size - 1u) - (this->members_.m_finish_off % block_size) : 0u);
796
+ }
797
+ }
798
+
799
+ //////////////////////////
800
+ // it_to_off / off_to_it
801
+ //////////////////////////
802
+
803
+ BOOST_CONTAINER_FORCEINLINE stored_size_type prot_it_to_off(const_iterator it) const
804
+ {
805
+ const ptr_alloc_ptr n = it.get_node();
806
+ BOOST_ASSERT(!this->members_.m_map == !n); //Both should be null or both non-null
807
+ if (n) {
808
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
809
+ return static_cast<stored_size_type>(std::size_t(n - this->members_.m_map)*block_size + std::size_t(it.get_cur() - *n));
810
+ }
811
+ else{
812
+ return 0;
813
+ }
814
+ }
815
+
816
+ BOOST_CONTAINER_FORCEINLINE iterator prot_off_to_it(std::size_t off) const
817
+ {
818
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
819
+ const ptr_alloc_ptr node = this->members_.m_map + difference_type(off/block_size);
820
+ return iterator(node ? *node + difference_type(off%block_size) : val_alloc_ptr(), node);
821
+ }
822
+
823
+ stored_size_type prot_it_to_start_off(const_iterator it) const
824
+ {
825
+ const size_type off = this->prot_it_to_off(it);
826
+ BOOST_ASSERT(off >= this->members_.m_start_off);
827
+ return static_cast<stored_size_type>(off - this->members_.m_start_off);
828
+ }
829
+
830
+ /////////////
831
+ // xxx_to_node
832
+ /////////////
833
+
834
+ BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr prot_off_to_node(std::size_t off) const
835
+ {
836
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
837
+ return this->members_.m_map + difference_type(off/block_size);
838
+ }
839
+
840
+ BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr prot_start_node() const
841
+ {
842
+ return this->prot_off_to_node(this->members_.m_start_off);
843
+ }
844
+
845
+ BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr prot_finish_node() const
846
+ {
847
+ return this->prot_off_to_node(this->members_.m_finish_off);
848
+ }
849
+
850
+ //
851
+ // xxx_to_cur_unchecked versions, faster but need non-default constructed deque
852
+ //
853
+ BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_off_to_cur_unchecked(std::size_t off) const
854
+ {
855
+ BOOST_ASSERT(!!this->members_.m_map);
856
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
857
+ const ptr_alloc_ptr node = this->members_.m_map + difference_type(off/block_size);
858
+ return *node + difference_type(off%block_size);
859
+ }
860
+
861
+ BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_start_cur_unchecked() const
862
+ {
863
+ return this->prot_off_to_cur_unchecked(this->members_.m_start_off);
864
+ }
865
+
866
+ BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_finish_cur_unchecked() const
867
+ {
868
+ return this->prot_off_to_cur_unchecked(this->members_.m_finish_off);
869
+ }
870
+
871
+ BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_last_cur_unchecked() const
872
+ {
873
+ BOOST_ASSERT(members_.m_start_off != members_.m_finish_off);
874
+ return this->prot_off_to_cur_unchecked(this->members_.m_finish_off-1u);
875
+ }
876
+
877
+ //
878
+ // functions returning iterators to different positions
879
+ //
880
+ BOOST_CONTAINER_FORCEINLINE const_iterator prot_start() const
881
+ { return this->prot_off_to_it(members_.m_start_off); }
882
+
883
+ BOOST_CONTAINER_FORCEINLINE iterator prot_start()
884
+ { return this->prot_off_to_it(members_.m_start_off); }
885
+
886
+ BOOST_CONTAINER_FORCEINLINE const_iterator prot_finish() const
887
+ { return this->prot_off_to_it(members_.m_finish_off); }
888
+
889
+ BOOST_CONTAINER_FORCEINLINE iterator prot_finish()
890
+ { return this->prot_off_to_it(members_.m_finish_off); }
891
+
892
+ BOOST_CONTAINER_FORCEINLINE const_iterator prot_nth(size_type n) const
893
+ { return this->prot_off_to_it(size_type(members_.m_start_off + n)); }
894
+
895
+ BOOST_CONTAINER_FORCEINLINE iterator prot_nth(size_type n)
896
+ { return this->prot_off_to_it(size_type(members_.m_start_off + n)); }
897
+
898
+ BOOST_CONTAINER_FORCEINLINE iterator prot_back_it()
899
+ {
900
+ BOOST_ASSERT(members_.m_start_off != members_.m_finish_off);
901
+ return this->prot_off_to_it(size_type(members_.m_finish_off - 1u));
902
+ }
903
+
904
+ //
905
+ // size/empty
906
+ //
907
+ BOOST_CONTAINER_FORCEINLINE size_type prot_size() const
908
+ { return size_type(this->members_.m_finish_off - this->members_.m_start_off); }
909
+
910
+ BOOST_CONTAINER_FORCEINLINE bool prot_empty() const
911
+ { return this->members_.m_finish_off == this->members_.m_start_off; }
912
+
913
+ //
914
+ // Functions to move start/finish indexes
915
+ //
916
+ BOOST_CONTAINER_FORCEINLINE void prot_inc_start()
917
+ { ++this->members_.m_start_off; }
918
+
919
+ BOOST_CONTAINER_FORCEINLINE void prot_dec_start()
920
+ { --this->members_.m_start_off; }
921
+
922
+ BOOST_CONTAINER_FORCEINLINE void prot_inc_finish()
923
+ { ++this->members_.m_finish_off; }
924
+
925
+ BOOST_CONTAINER_FORCEINLINE void prot_dec_finish()
926
+ { --this->members_.m_finish_off; }
927
+
928
+ BOOST_CONTAINER_FORCEINLINE void prot_dec_finish(std::size_t n)
929
+ { this->members_.m_finish_off = static_cast<stored_size_type>(this->members_.m_finish_off - n); }
930
+
931
+ BOOST_CONTAINER_FORCEINLINE void prot_inc_finish(std::size_t n)
932
+ { this->members_.m_finish_off = static_cast<stored_size_type>(this->members_.m_finish_off + n); }
933
+
934
+ BOOST_CONTAINER_FORCEINLINE void prot_dec_start(std::size_t n)
935
+ { this->members_.m_start_off = static_cast<stored_size_type>(this->members_.m_start_off - n); }
936
+
937
+ BOOST_CONTAINER_FORCEINLINE void prot_inc_start(std::size_t n)
938
+ { this->members_.m_start_off = static_cast<stored_size_type>(this->members_.m_start_off + n); }
939
+
940
+ //
941
+ // Functions to obtain indexes from nodes
942
+ //
943
+ BOOST_CONTAINER_FORCEINLINE stored_size_type prot_non_null_node_to_off(ptr_alloc_ptr n) const
944
+ {
945
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
946
+ return static_cast<stored_size_type>(std::size_t(n - this->members_.m_map)*block_size);
947
+ }
948
+
949
+ void prot_set_start_finish_from_node(size_type node_idx, size_type n_elements)
950
+ {
951
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
952
+ this->members_.m_start_off = static_cast<stored_size_type>(node_idx*block_size);
953
+ this->members_.m_finish_off = static_cast<stored_size_type>(this->members_.m_start_off + n_elements);
954
+ }
955
+
956
+ inline void prot_start_update_node(ptr_alloc_ptr new_start)
957
+ {
958
+ //iG: to-do: optimizable avoiding some division/remainder
959
+ std::size_t new_block_off = prot_non_null_node_to_off(new_start);
960
+ this->members_.m_start_off = static_cast<stored_size_type>(new_block_off + (this->members_.m_start_off % get_block_size()));
961
+ }
962
+
963
+ inline void prot_finish_update_node(ptr_alloc_ptr new_finish)
964
+ {
965
+ //iG: to-do: optimizable avoiding some division/remainder
966
+ std::size_t new_block_off = prot_non_null_node_to_off(new_finish);
967
+ this->members_.m_finish_off = static_cast<stored_size_type>(new_block_off + (this->members_.m_finish_off % get_block_size()));
968
+ }
969
+
970
+ inline void prot_reset_finish_to_start()
971
+ { this->members_.m_finish_off = this->members_.m_start_off; }
972
+
973
+ inline void prot_reset_start_to_finish()
974
+ { this->members_.m_start_off = this->members_.m_finish_off; }
975
+
976
+ inline val_alloc_val *prot_push_back_simple_pos() const
977
+ {
978
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
979
+ const std::size_t last_in_block = block_size - 1u;
980
+ const ptr_alloc_val *const map = boost::movelib::to_raw_pointer(this->members_.m_map);
981
+ if(BOOST_LIKELY(map != 0)) {
982
+ const std::size_t off = this->members_.m_finish_off;
983
+ const std::size_t rem = off % block_size;
984
+ if(BOOST_LIKELY(rem != last_in_block)){
985
+ return boost::movelib::to_raw_pointer(map[difference_type(off/block_size)]) + difference_type(rem);
986
+ }
987
+ }
988
+ return 0;
989
+ }
990
+
991
+ inline val_alloc_val *prot_push_front_simple_pos() const
992
+ {
993
+ BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
994
+ //No need to check !m_map, as m_start_off is zero in that case
995
+ const std::size_t off = this->members_.m_start_off;
996
+ const std::size_t rem = off % block_size;
997
+ if(BOOST_LIKELY(rem != 0u)){
998
+ return boost::movelib::to_raw_pointer(this->members_.m_map[difference_type(off/block_size)]) + difference_type(rem-1u);
999
+ }
1000
+ return 0;
1001
+ }
1002
+
1003
+ BOOST_CONTAINER_FORCEINLINE bool prot_pop_back_simple_available() const
1004
+ {
1005
+ return (this->members_.m_finish_off % get_block_size()) != 0u;
1006
+ }
974
1007
 
975
- inline allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
976
- { return members_; }
1008
+ BOOST_CONTAINER_FORCEINLINE bool prot_pop_front_simple_available() const
1009
+ {
1010
+ return size_type(this->members_.m_start_off % get_block_size()) != size_type(get_block_size() - 1u);
1011
+ }
977
1012
 
978
- inline const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
979
- { return members_; }
980
1013
  };
981
1014
  #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
982
1015
 
@@ -1032,8 +1065,9 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1032
1065
  BOOST_CONTAINER_STATIC_ASSERT((dtl::is_same<value_type, typename allocator_traits<ValAllocator>::value_type>::value));
1033
1066
 
1034
1067
  BOOST_COPYABLE_AND_MOVABLE(deque)
1035
- typedef typename Base::ptr_alloc_ptr index_pointer;
1036
- typedef allocator_traits<ValAllocator> allocator_traits_type;
1068
+ typedef typename Base::ptr_alloc_ptr index_pointer;
1069
+ typedef allocator_traits<ValAllocator> allocator_traits_type;
1070
+ typedef typename Base::stored_size_type stored_size_type;
1037
1071
 
1038
1072
  #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1039
1073
 
@@ -1043,6 +1077,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1043
1077
 
1044
1078
  using Base::get_block_size;
1045
1079
 
1080
+ static const std::size_t is_reservable = Base::is_reservable;
1046
1081
 
1047
1082
  //////////////////////////////////////////////
1048
1083
  //
@@ -1080,7 +1115,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1080
1115
  : Base(n, allocator_type())
1081
1116
  {
1082
1117
  dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1083
- proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1118
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
1084
1119
  //deque_base will deallocate in case of exception...
1085
1120
  }
1086
1121
 
@@ -1097,7 +1132,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1097
1132
  : Base(n, allocator_type())
1098
1133
  {
1099
1134
  dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1100
- proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1135
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
1101
1136
  //deque_base will deallocate in case of exception...
1102
1137
  }
1103
1138
 
@@ -1112,7 +1147,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1112
1147
  : Base(n, a)
1113
1148
  {
1114
1149
  dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1115
- proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1150
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
1116
1151
  //deque_base will deallocate in case of exception...
1117
1152
  }
1118
1153
 
@@ -1129,7 +1164,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1129
1164
  : Base(n, a)
1130
1165
  {
1131
1166
  dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1132
- proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
1167
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
1133
1168
  //deque_base will deallocate in case of exception...
1134
1169
  }
1135
1170
 
@@ -1142,7 +1177,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1142
1177
  //! <b>Complexity</b>: Linear to n.
1143
1178
  inline deque(size_type n, const value_type& value)
1144
1179
  : Base(n, allocator_type())
1145
- { this->priv_fill_initialize(value); }
1180
+ { this->priv_fill_initialize(n, value); }
1146
1181
 
1147
1182
  //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1148
1183
  //! and inserts n copies of value.
@@ -1153,7 +1188,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1153
1188
  //! <b>Complexity</b>: Linear to n.
1154
1189
  inline deque(size_type n, const value_type& value, const allocator_type& a)
1155
1190
  : Base(n, a)
1156
- { this->priv_fill_initialize(value); }
1191
+ { this->priv_fill_initialize(n, value); }
1157
1192
 
1158
1193
  //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
1159
1194
  //! and inserts a copy of the range [first, last) in the deque.
@@ -1217,9 +1252,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1217
1252
  : Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
1218
1253
  {
1219
1254
  if(x.size()){
1220
- this->priv_initialize_map(x.size());
1221
- boost::container::uninitialized_copy_alloc
1222
- (this->alloc(), x.begin(), x.end(), this->members_.m_start);
1255
+ this->prot_initialize_map_and_nodes(x.size());
1256
+ this->priv_segmented_uninitialized_copy_alloc_n(x.begin(), x.size(), this->begin());
1223
1257
  }
1224
1258
  }
1225
1259
 
@@ -1244,9 +1278,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1244
1278
  : Base(a)
1245
1279
  {
1246
1280
  if(x.size()){
1247
- this->priv_initialize_map(x.size());
1248
- boost::container::uninitialized_copy_alloc
1249
- (this->alloc(), x.begin(), x.end(), this->members_.m_start);
1281
+ this->prot_initialize_map_and_nodes(x.size());
1282
+ this->priv_segmented_uninitialized_copy_alloc_n(x.begin(), x.size(), this->begin());
1250
1283
  }
1251
1284
  }
1252
1285
 
@@ -1265,10 +1298,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1265
1298
  }
1266
1299
  else{
1267
1300
  if(x.size()){
1268
- this->priv_initialize_map(x.size());
1269
- boost::container::uninitialized_copy_alloc
1270
- ( this->alloc(), boost::make_move_iterator(x.begin())
1271
- , boost::make_move_iterator(x.end()), this->members_.m_start);
1301
+ this->prot_initialize_map_and_nodes(x.size());
1302
+ this->priv_segmented_uninitialized_move_alloc_n(x.begin(), x.size(), this->begin());
1272
1303
  }
1273
1304
  }
1274
1305
  }
@@ -1281,7 +1312,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1281
1312
  //! <b>Complexity</b>: Linear to the number of elements.
1282
1313
  inline ~deque() BOOST_NOEXCEPT_OR_NOTHROW
1283
1314
  {
1284
- this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
1315
+ this->prot_destroy_range(this->prot_start(), this->prot_finish());
1285
1316
  }
1286
1317
 
1287
1318
  //! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -1357,7 +1388,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1357
1388
  //! <b>Complexity</b>: Linear to n.
1358
1389
  inline void assign(size_type n, const T& val)
1359
1390
  {
1360
- this->assign(c_it(val, n), c_it());
1391
+ dtl::insert_n_copies_proxy<ValAllocator> proxy(val);
1392
+ this->priv_assign(n, proxy);
1361
1393
  }
1362
1394
 
1363
1395
  //! <b>Effects</b>: Assigns the the range [first, last) to *this.
@@ -1399,16 +1431,14 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1399
1431
  >::type * = 0
1400
1432
  )
1401
1433
  {
1402
- const size_type len = boost::container::iterator_udistance(first, last);
1403
- if (len > size()) {
1404
- FwdIt mid = first;
1405
- boost::container::iterator_uadvance(mid, this->size());
1406
- boost::container::copy(first, mid, begin());
1407
- this->insert(this->cend(), mid, last);
1408
- }
1409
- else{
1410
- this->erase(boost::container::copy(first, last, this->begin()), cend());
1434
+ typedef typename iter_size<FwdIt>::type it_size_type;
1435
+ const it_size_type sz = boost::container::iterator_udistance(first, last);
1436
+ if (BOOST_UNLIKELY(sz > size_type(-1))){
1437
+ boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
1411
1438
  }
1439
+ const size_type n = static_cast<size_type>(sz);
1440
+ dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
1441
+ this->priv_assign(n, proxy);
1412
1442
  }
1413
1443
  #endif
1414
1444
 
@@ -1467,7 +1497,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1467
1497
  //! <b>Complexity</b>: Constant.
1468
1498
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1469
1499
  iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
1470
- { return this->members_.m_start; }
1500
+ { return this->prot_start(); }
1471
1501
 
1472
1502
  //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
1473
1503
  //!
@@ -1476,7 +1506,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1476
1506
  //! <b>Complexity</b>: Constant.
1477
1507
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1478
1508
  const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
1479
- { return this->members_.m_start; }
1509
+ { return this->prot_start(); }
1480
1510
 
1481
1511
  //! <b>Effects</b>: Returns an iterator to the end of the deque.
1482
1512
  //!
@@ -1485,7 +1515,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1485
1515
  //! <b>Complexity</b>: Constant.
1486
1516
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1487
1517
  iterator end() BOOST_NOEXCEPT_OR_NOTHROW
1488
- { return this->members_.m_finish; }
1518
+ { return this->prot_finish(); }
1489
1519
 
1490
1520
  //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
1491
1521
  //!
@@ -1494,7 +1524,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1494
1524
  //! <b>Complexity</b>: Constant.
1495
1525
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1496
1526
  const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
1497
- { return this->members_.m_finish; }
1527
+ { return this->prot_finish(); }
1498
1528
 
1499
1529
  //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
1500
1530
  //! of the reversed deque.
@@ -1504,7 +1534,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1504
1534
  //! <b>Complexity</b>: Constant.
1505
1535
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1506
1536
  reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
1507
- { return reverse_iterator(this->members_.m_finish); }
1537
+ { return reverse_iterator(this->prot_finish()); }
1508
1538
 
1509
1539
  //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1510
1540
  //! of the reversed deque.
@@ -1514,7 +1544,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1514
1544
  //! <b>Complexity</b>: Constant.
1515
1545
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1516
1546
  const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1517
- { return const_reverse_iterator(this->members_.m_finish); }
1547
+ { return const_reverse_iterator(this->prot_finish()); }
1518
1548
 
1519
1549
  //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
1520
1550
  //! of the reversed deque.
@@ -1524,7 +1554,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1524
1554
  //! <b>Complexity</b>: Constant.
1525
1555
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1526
1556
  reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
1527
- { return reverse_iterator(this->members_.m_start); }
1557
+ { return reverse_iterator(this->prot_start()); }
1528
1558
 
1529
1559
  //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1530
1560
  //! of the reversed deque.
@@ -1534,7 +1564,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1534
1564
  //! <b>Complexity</b>: Constant.
1535
1565
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1536
1566
  const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
1537
- { return const_reverse_iterator(this->members_.m_start); }
1567
+ { return const_reverse_iterator(this->prot_start()); }
1538
1568
 
1539
1569
  //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
1540
1570
  //!
@@ -1543,7 +1573,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1543
1573
  //! <b>Complexity</b>: Constant.
1544
1574
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1545
1575
  const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1546
- { return this->members_.m_start; }
1576
+ { return this->prot_start(); }
1547
1577
 
1548
1578
  //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
1549
1579
  //!
@@ -1552,7 +1582,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1552
1582
  //! <b>Complexity</b>: Constant.
1553
1583
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1554
1584
  const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
1555
- { return this->members_.m_finish; }
1585
+ { return this->prot_finish(); }
1556
1586
 
1557
1587
  //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
1558
1588
  //! of the reversed deque.
@@ -1562,7 +1592,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1562
1592
  //! <b>Complexity</b>: Constant.
1563
1593
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1564
1594
  const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
1565
- { return const_reverse_iterator(this->members_.m_finish); }
1595
+ { return const_reverse_iterator(this->prot_finish()); }
1566
1596
 
1567
1597
  //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
1568
1598
  //! of the reversed deque.
@@ -1572,7 +1602,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1572
1602
  //! <b>Complexity</b>: Constant.
1573
1603
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1574
1604
  const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
1575
- { return const_reverse_iterator(this->members_.m_start); }
1605
+ { return const_reverse_iterator(this->prot_start()); }
1576
1606
 
1577
1607
  //////////////////////////////////////////////
1578
1608
  //
@@ -1587,7 +1617,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1587
1617
  //! <b>Complexity</b>: Constant.
1588
1618
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1589
1619
  bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
1590
- { return this->members_.m_finish == this->members_.m_start; }
1620
+ { return this->prot_empty(); }
1591
1621
 
1592
1622
  //! <b>Effects</b>: Returns the number of the elements contained in the deque.
1593
1623
  //!
@@ -1596,7 +1626,75 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1596
1626
  //! <b>Complexity</b>: Constant.
1597
1627
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1598
1628
  size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
1599
- { return size_type(this->members_.m_finish - this->members_.m_start); }
1629
+ { return this->prot_size(); }
1630
+
1631
+ //! <b>Effects</b>: Returns the number of the elements that can be inserted
1632
+ //! at the back without allocating additional memory.
1633
+ //!
1634
+ //! <b>Throws</b>: Nothing.
1635
+ //!
1636
+ //! <b>Complexity</b>: Constant.
1637
+ //!
1638
+ //! <b>Note</b>: Non-standard extension.
1639
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1640
+ size_type back_capacity() const BOOST_NOEXCEPT_OR_NOTHROW
1641
+ { return size_type(this->size() + this->prot_back_free_capacity()); }
1642
+
1643
+ //! <b>Effects</b>: Returns the number of the elements that can be inserted
1644
+ //! at the front without allocating additional memory.
1645
+ //!
1646
+ //! <b>Throws</b>: Nothing.
1647
+ //!
1648
+ //! <b>Complexity</b>: Constant.
1649
+ //!
1650
+ //! <b>Note</b>: Non-standard extension.
1651
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
1652
+ size_type front_capacity() const BOOST_NOEXCEPT_OR_NOTHROW
1653
+ { return size_type(this->size() + this->prot_front_free_capacity()); }
1654
+
1655
+ //! <b>Requires</b>: The container must be "reservable" (is_reservable == true)
1656
+ //!
1657
+ //! <b>Effects</b>: If n is less than or equal to back_capacity() or the container is not reservable,
1658
+ //! this call has no effect. Otherwise, if it is a request for allocation of additional memory.
1659
+ //! If the request is successful, then back_capacity() is greater than or equal to
1660
+ //! n; otherwise, back_capacity() is unchanged. In either case, size() is unchanged.
1661
+ //!
1662
+ //! <b>Throws</b>: If memory allocation throws.
1663
+ //!
1664
+ //! <b>Complexity</b>: Linear to n.
1665
+ //!
1666
+ //! <b>Note</b>: Non-standard extension.
1667
+ void reserve_back(size_type n)
1668
+ {
1669
+ (void)n;
1670
+ BOOST_IF_CONSTEXPR(is_reservable){
1671
+ const size_type cur_back_cap = this->back_capacity();
1672
+ if (this->back_capacity() < n)
1673
+ this->priv_reserve_elements_at_back(size_type(n - cur_back_cap) );
1674
+ }
1675
+ }
1676
+
1677
+ //! <b>Requires</b>: The container must be "reservable" (is_reservable == true)
1678
+ //!
1679
+ //! <b>Effects</b>: If n is less than or equal to back_capacity() or the container is not reservable,
1680
+ //! this call has no effect. Otherwise, if it is a request for allocation of additional memory.
1681
+ //! If the request is successful, then back_capacity() is greater than or equal to
1682
+ //! n; otherwise, back_capacity() is unchanged. In either case, size() is unchanged.
1683
+ //!
1684
+ //! <b>Throws</b>: If memory allocation throws.
1685
+ //!
1686
+ //! <b>Complexity</b>: Linear to n.
1687
+ //!
1688
+ //! <b>Note</b>: Non-standard extension.
1689
+ void reserve_front(size_type n)
1690
+ {
1691
+ (void)n;
1692
+ BOOST_IF_CONSTEXPR(is_reservable){
1693
+ const size_type cur_back_cap = this->front_capacity();
1694
+ if (this->front_capacity() < n)
1695
+ this->priv_reserve_elements_at_front(size_type(n - cur_back_cap) );
1696
+ }
1697
+ }
1600
1698
 
1601
1699
  //! <b>Effects</b>: Returns the largest possible size of the deque.
1602
1700
  //!
@@ -1615,13 +1713,13 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1615
1713
  //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1616
1714
  void resize(size_type new_size)
1617
1715
  {
1618
- const size_type len = size();
1716
+ const size_type len = this->size();
1619
1717
  if (new_size < len)
1620
- this->priv_erase_last_n(len - new_size);
1718
+ this->priv_erase_last_n(size_type(len - new_size));
1621
1719
  else{
1622
- const size_type n = new_size - this->size();
1720
+ const size_type n = size_type(new_size - this->size());
1623
1721
  dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
1624
- priv_insert_back_aux_impl(n, proxy);
1722
+ this->priv_insert_back_aux_impl(n, proxy);
1625
1723
  }
1626
1724
  }
1627
1725
 
@@ -1637,11 +1735,11 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1637
1735
  {
1638
1736
  const size_type len = size();
1639
1737
  if (new_size < len)
1640
- this->priv_erase_last_n(len - new_size);
1738
+ this->priv_erase_last_n(size_type(len - new_size));
1641
1739
  else{
1642
- const size_type n = new_size - this->size();
1740
+ const size_type n = size_type(new_size - this->size());
1643
1741
  dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
1644
- priv_insert_back_aux_impl(n, proxy);
1742
+ this->priv_insert_back_aux_impl(n, proxy);
1645
1743
  }
1646
1744
  }
1647
1745
 
@@ -1653,11 +1751,14 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1653
1751
  //! <b>Complexity</b>: Linear to the difference between size() and new_size.
1654
1752
  void resize(size_type new_size, const value_type& x)
1655
1753
  {
1656
- const size_type len = size();
1657
- if (new_size < len)
1658
- this->erase(this->members_.m_start + difference_type(new_size), this->members_.m_finish);
1659
- else
1660
- this->insert(this->members_.m_finish, new_size - len, x);
1754
+ const size_type sz = this->size();
1755
+ if (new_size < sz)
1756
+ this->priv_erase_last_n(size_type(sz - new_size));
1757
+ else {
1758
+ const size_type n = size_type(new_size - sz);
1759
+ dtl::insert_n_copies_proxy<ValAllocator> proxy(x);
1760
+ this->priv_insert_back_aux_impl(n, proxy);
1761
+ }
1661
1762
  }
1662
1763
 
1663
1764
  //! <b>Effects</b>: Tries to deallocate the excess of memory created
@@ -1673,7 +1774,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1673
1774
  //so there is nothing to do except for
1674
1775
  //empty deque
1675
1776
  if(this->empty()){
1676
- this->priv_clear_map();
1777
+ this->prot_clear_map();
1677
1778
  }
1678
1779
  }
1679
1780
 
@@ -1695,7 +1796,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1695
1796
  reference front() BOOST_NOEXCEPT_OR_NOTHROW
1696
1797
  {
1697
1798
  BOOST_ASSERT(!this->empty());
1698
- return *this->members_.m_start;
1799
+ return *this->prot_start_cur_unchecked();
1699
1800
  }
1700
1801
 
1701
1802
  //! <b>Requires</b>: !empty()
@@ -1710,7 +1811,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1710
1811
  const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
1711
1812
  {
1712
1813
  BOOST_ASSERT(!this->empty());
1713
- return *this->members_.m_start;
1814
+ return *this->prot_start_cur_unchecked();
1714
1815
  }
1715
1816
 
1716
1817
  //! <b>Requires</b>: !empty()
@@ -1725,7 +1826,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1725
1826
  reference back() BOOST_NOEXCEPT_OR_NOTHROW
1726
1827
  {
1727
1828
  BOOST_ASSERT(!this->empty());
1728
- return *(end()-1);
1829
+ return *this->prot_last_cur_unchecked();
1729
1830
  }
1730
1831
 
1731
1832
  //! <b>Requires</b>: !empty()
@@ -1740,7 +1841,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1740
1841
  const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
1741
1842
  {
1742
1843
  BOOST_ASSERT(!this->empty());
1743
- return *(cend()-1);
1844
+ return *this->prot_last_cur_unchecked();
1744
1845
  }
1745
1846
 
1746
1847
  //! <b>Requires</b>: size() > n.
@@ -1755,7 +1856,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1755
1856
  reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1756
1857
  {
1757
1858
  BOOST_ASSERT(this->size() > n);
1758
- return this->members_.m_start[difference_type(n)];
1859
+ return *this->prot_nth(n);
1759
1860
  }
1760
1861
 
1761
1862
  //! <b>Requires</b>: size() > n.
@@ -1770,7 +1871,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1770
1871
  const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1771
1872
  {
1772
1873
  BOOST_ASSERT(this->size() > n);
1773
- return this->members_.m_start[difference_type(n)];
1874
+ return *this->prot_nth(n);
1774
1875
  }
1775
1876
 
1776
1877
  //! <b>Requires</b>: size() >= n.
@@ -1788,7 +1889,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1788
1889
  iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1789
1890
  {
1790
1891
  BOOST_ASSERT(this->size() >= n);
1791
- return iterator(this->begin()+difference_type(n));
1892
+ return this->prot_nth(n);
1792
1893
  }
1793
1894
 
1794
1895
  //! <b>Requires</b>: size() >= n.
@@ -1806,7 +1907,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1806
1907
  const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1807
1908
  {
1808
1909
  BOOST_ASSERT(this->size() >= n);
1809
- return const_iterator(this->cbegin()+difference_type(n));
1910
+ return this->prot_nth(n);
1810
1911
  }
1811
1912
 
1812
1913
  //! <b>Requires</b>: begin() <= p <= end().
@@ -1892,14 +1993,14 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1892
1993
  template <class... Args>
1893
1994
  reference emplace_front(BOOST_FWD_REF(Args)... args)
1894
1995
  {
1895
- if(this->priv_push_front_simple_available()){
1896
- reference r = *this->priv_push_front_simple_pos();
1996
+ value_type *pr = this->prot_push_front_simple_pos();
1997
+ if(BOOST_LIKELY(pr != 0)){
1897
1998
  allocator_traits_type::construct
1898
1999
  ( this->alloc()
1899
- , this->priv_push_front_simple_pos()
2000
+ , pr
1900
2001
  , boost::forward<Args>(args)...);
1901
- this->priv_push_front_simple_commit();
1902
- return r;
2002
+ this->prot_dec_start();
2003
+ return *pr;
1903
2004
  }
1904
2005
  else{
1905
2006
  typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
@@ -1918,14 +2019,12 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1918
2019
  template <class... Args>
1919
2020
  reference emplace_back(BOOST_FWD_REF(Args)... args)
1920
2021
  {
1921
- if(this->priv_push_back_simple_available()){
1922
- reference r = *this->priv_push_back_simple_pos();
2022
+ value_type *pr = this->prot_push_back_simple_pos();
2023
+ if(BOOST_LIKELY(pr != 0)){
1923
2024
  allocator_traits_type::construct
1924
- ( this->alloc()
1925
- , this->priv_push_back_simple_pos()
1926
- , boost::forward<Args>(args)...);
1927
- this->priv_push_back_simple_commit();
1928
- return r;
2025
+ ( this->alloc(), pr, boost::forward<Args>(args)...);
2026
+ this->prot_inc_finish();
2027
+ return *pr;
1929
2028
  }
1930
2029
  else{
1931
2030
  typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
@@ -1945,18 +2044,20 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1945
2044
  template <class... Args>
1946
2045
  iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
1947
2046
  {
1948
- BOOST_ASSERT(this->priv_in_range_or_end(p));
1949
- if(p == this->cbegin()){
2047
+ const size_type elemsbefore = this->prot_it_to_start_off(p);
2048
+ const size_type length = this->prot_size();
2049
+
2050
+ if (!elemsbefore) {
1950
2051
  this->emplace_front(boost::forward<Args>(args)...);
1951
2052
  return this->begin();
1952
2053
  }
1953
- else if(p == this->cend()){
2054
+ else if (elemsbefore == length) {
1954
2055
  this->emplace_back(boost::forward<Args>(args)...);
1955
- return (this->end()-1);
2056
+ return this->prot_back_it();
1956
2057
  }
1957
- else{
2058
+ else {
1958
2059
  typedef dtl::insert_emplace_proxy<ValAllocator, Args...> type;
1959
- return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
2060
+ return this->priv_insert_middle_aux_impl(elemsbefore, 1, type(boost::forward<Args>(args)...));
1960
2061
  }
1961
2062
  }
1962
2063
 
@@ -1966,12 +2067,12 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1966
2067
  BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1967
2068
  reference emplace_front(BOOST_MOVE_UREF##N)\
1968
2069
  {\
1969
- if(priv_push_front_simple_available()){\
1970
- reference r = *this->priv_push_front_simple_pos();\
2070
+ value_type *pr = this->prot_push_front_simple_pos();\
2071
+ if(BOOST_LIKELY(pr != 0)){\
1971
2072
  allocator_traits_type::construct\
1972
- ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1973
- priv_push_front_simple_commit();\
1974
- return r;\
2073
+ ( this->alloc(), pr BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2074
+ this->prot_dec_start();\
2075
+ return *pr;\
1975
2076
  }\
1976
2077
  else{\
1977
2078
  typedef dtl::insert_nonmovable_emplace_proxy##N\
@@ -1983,12 +2084,12 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1983
2084
  BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
1984
2085
  reference emplace_back(BOOST_MOVE_UREF##N)\
1985
2086
  {\
1986
- if(priv_push_back_simple_available()){\
1987
- reference r = *this->priv_push_back_simple_pos();\
2087
+ value_type *pr = this->prot_push_back_simple_pos();\
2088
+ if(BOOST_LIKELY(pr != 0)){\
1988
2089
  allocator_traits_type::construct\
1989
- ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1990
- priv_push_back_simple_commit();\
1991
- return r;\
2090
+ ( this->alloc(), pr BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2091
+ this->prot_inc_finish();\
2092
+ return *pr;\
1992
2093
  }\
1993
2094
  else{\
1994
2095
  typedef dtl::insert_nonmovable_emplace_proxy##N\
@@ -2000,21 +2101,23 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2000
2101
  BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
2001
2102
  iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2002
2103
  {\
2003
- BOOST_ASSERT(this->priv_in_range_or_end(p));\
2004
- if(p == this->cbegin()){\
2104
+ const size_type elemsbefore = this->prot_it_to_start_off(p);\
2105
+ const size_type length = this->prot_size();\
2106
+ \
2107
+ if (!elemsbefore) {\
2005
2108
  this->emplace_front(BOOST_MOVE_FWD##N);\
2006
2109
  return this->begin();\
2007
2110
  }\
2008
- else if(p == cend()){\
2111
+ else if (elemsbefore == length) {\
2009
2112
  this->emplace_back(BOOST_MOVE_FWD##N);\
2010
- return (--this->end());\
2113
+ return this->prot_back_it();\
2011
2114
  }\
2012
- else{\
2115
+ else {\
2013
2116
  typedef dtl::insert_emplace_proxy_arg##N\
2014
2117
  <ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
2015
- return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
2118
+ return this->priv_insert_middle_aux_impl(elemsbefore, 1, type(BOOST_MOVE_FWD##N));\
2016
2119
  }\
2017
- }
2120
+ }\
2018
2121
  //
2019
2122
  BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
2020
2123
  #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
@@ -2101,8 +2204,9 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2101
2204
  //! <b>Complexity</b>: Linear to n.
2102
2205
  inline iterator insert(const_iterator pos, size_type n, const value_type& x)
2103
2206
  {
2104
- //Range check of p is done by insert()
2105
- return this->insert(pos, c_it(x, n), c_it());
2207
+ BOOST_ASSERT(this->priv_in_range_or_end(pos));
2208
+ dtl::insert_n_copies_proxy<ValAllocator> proxy(x);
2209
+ return this->priv_insert_aux_impl(pos, n, proxy);
2106
2210
  }
2107
2211
 
2108
2212
  //! <b>Requires</b>: pos must be a valid iterator of *this.
@@ -2168,8 +2272,16 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2168
2272
  )
2169
2273
  {
2170
2274
  BOOST_ASSERT(this->priv_in_range_or_end(p));
2275
+
2276
+ typedef typename iter_size<FwdIt>::type it_size_type;
2277
+ const it_size_type sz = boost::container::iterator_udistance(first, last);
2278
+ if (BOOST_UNLIKELY(sz > size_type(-1))){
2279
+ boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
2280
+ }
2281
+ const size_type n = static_cast<size_type>(sz);
2282
+
2171
2283
  dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
2172
- return priv_insert_aux_impl(p, boost::container::iterator_udistance(first, last), proxy);
2284
+ return this->priv_insert_aux_impl( p, n, proxy);
2173
2285
  }
2174
2286
  #endif
2175
2287
 
@@ -2181,12 +2293,12 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2181
2293
  void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
2182
2294
  {
2183
2295
  BOOST_ASSERT(!this->empty());
2184
- if (this->members_.m_start.m_cur != this->members_.m_start.get_last() - 1) {
2296
+ if (BOOST_LIKELY(this->prot_pop_front_simple_available())) {
2185
2297
  allocator_traits_type::destroy
2186
2298
  ( this->alloc()
2187
- , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
2299
+ , boost::movelib::to_raw_pointer(this->prot_start_cur_unchecked())
2188
2300
  );
2189
- ++this->members_.m_start.m_cur;
2301
+ this->prot_inc_start();
2190
2302
  }
2191
2303
  else
2192
2304
  this->priv_pop_front_aux();
@@ -2200,11 +2312,11 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2200
2312
  void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
2201
2313
  {
2202
2314
  BOOST_ASSERT(!this->empty());
2203
- if (this->members_.m_finish.m_cur != this->members_.m_finish.get_first()) {
2204
- --this->members_.m_finish.m_cur;
2315
+ if (BOOST_LIKELY(this->prot_pop_back_simple_available())) {
2316
+ this->prot_dec_finish();
2205
2317
  allocator_traits_type::destroy
2206
2318
  ( this->alloc()
2207
- , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
2319
+ , boost::movelib::to_raw_pointer(this->prot_finish_cur_unchecked())
2208
2320
  );
2209
2321
  }
2210
2322
  else
@@ -2224,16 +2336,18 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2224
2336
  BOOST_ASSERT(this->priv_in_range(pos));
2225
2337
  iterator next = pos.unconst();
2226
2338
  ++next;
2227
- size_type index = size_type(pos - this->members_.m_start);
2228
- if (index < (this->size()/2)) {
2229
- boost::container::move_backward(this->begin(), pos.unconst(), next);
2339
+ const size_type index = this->prot_it_to_start_off(pos);
2340
+ const size_type sz = this->prot_size();
2341
+ if (index < sz/2u) {
2342
+ this->priv_segmented_move_backward_n(pos.unconst(), index, next);
2230
2343
  pop_front();
2344
+ return next;
2231
2345
  }
2232
2346
  else {
2233
- boost::container::move(next, this->end(), pos.unconst());
2347
+ this->priv_segmented_move_n(next, size_type(sz - size_type(index + 1u)), pos.unconst());
2234
2348
  pop_back();
2349
+ return pos.unconst();
2235
2350
  }
2236
- return this->members_.m_start + difference_type(index);
2237
2351
  }
2238
2352
 
2239
2353
  //! <b>Effects</b>: Erases the elements pointed by [first, last).
@@ -2248,28 +2362,29 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2248
2362
  {
2249
2363
  BOOST_ASSERT(first == last ||
2250
2364
  (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
2251
- if (first == this->members_.m_start && last == this->members_.m_finish) {
2365
+ const size_type n = static_cast<size_type>(last - first);
2366
+ if (n == this->prot_size()) {
2252
2367
  this->clear();
2253
- return this->members_.m_finish;
2368
+ return this->end();
2254
2369
  }
2255
2370
  else {
2256
- const size_type n = static_cast<size_type>(last - first);
2257
- const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
2258
- if (elems_before < (this->size() - n) - elems_before) {
2259
- boost::container::move_backward(begin(), first.unconst(), last.unconst());
2260
- iterator new_start = this->members_.m_start + difference_type(n);
2261
- this->priv_destroy_range(this->members_.m_start, new_start);
2262
- this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
2263
- this->members_.m_start = new_start;
2371
+ const size_type elems_before = this->prot_it_to_start_off(first);
2372
+ const size_type elems_after = size_type(this->prot_size() - n - elems_before);
2373
+ if (elems_before < elems_after) {
2374
+ const iterator old_start = this->begin();
2375
+ iterator new_start = this->priv_segmented_move_backward_n(first.unconst(), elems_before, last.unconst());
2376
+ this->prot_destroy_range(old_start, new_start);
2377
+ this->prot_deallocate_nodes_if_not_reservable(old_start.get_node(), new_start.m_node);
2378
+ this->prot_inc_start(n);
2264
2379
  }
2265
2380
  else {
2266
- boost::container::move(last.unconst(), end(), first.unconst());
2267
- iterator new_finish = this->members_.m_finish - difference_type(n);
2268
- this->priv_destroy_range(new_finish, this->members_.m_finish);
2269
- this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
2270
- this->members_.m_finish = new_finish;
2381
+ const iterator old_finish = this->end();
2382
+ iterator new_finish = this->priv_segmented_move_n(last.unconst(), elems_after, first.unconst());
2383
+ this->prot_destroy_range(new_finish, old_finish);
2384
+ this->prot_deallocate_nodes_if_not_reservable(new_finish.m_node + 1, old_finish.get_node() + 1);
2385
+ this->prot_dec_finish(n);
2271
2386
  }
2272
- return this->members_.m_start + difference_type(elems_before);
2387
+ return this->nth(elems_before);
2273
2388
  }
2274
2389
  }
2275
2390
 
@@ -2295,24 +2410,25 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2295
2410
  //! <b>Complexity</b>: Linear to the number of elements in the deque.
2296
2411
  void clear() BOOST_NOEXCEPT_OR_NOTHROW
2297
2412
  {
2298
- if (this->members_.m_finish != this->members_.m_start) {
2299
-
2300
- for (index_pointer node = this->members_.m_start.m_node + 1;
2301
- node < this->members_.m_finish.m_node;
2302
- ++node) {
2303
- this->priv_destroy_range(*node, *node + get_block_ssize());
2304
- this->priv_deallocate_node(*node);
2413
+ if (!this->empty()) {
2414
+ const iterator start = this->prot_start();
2415
+ const iterator finish = this->prot_finish();
2416
+ const index_pointer start_node = start.get_node();
2417
+ const index_pointer finish_node = finish.get_node();
2418
+ for (index_pointer node = start_node + 1; node < finish_node; ++node) {
2419
+ this->prot_destroy_range(*node, *node + get_block_ssize());
2420
+ this->prot_deallocate_node_if_not_reservable(*node);
2305
2421
  }
2306
2422
 
2307
- if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
2308
- this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.get_last());
2309
- this->priv_destroy_range(this->members_.m_finish.get_first(), this->members_.m_finish.m_cur);
2310
- this->priv_deallocate_node(this->members_.m_finish.get_first());
2423
+ if (start_node != finish_node) {
2424
+ this->prot_destroy_range(start.get_cur(), start.get_last());
2425
+ this->prot_destroy_range(finish.get_first(), finish.get_cur());
2426
+ this->prot_deallocate_node_if_not_reservable(finish.get_first());
2311
2427
  }
2312
2428
  else
2313
- this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
2429
+ this->prot_destroy_range(start.get_cur(), finish.get_cur());
2314
2430
 
2315
- this->members_.m_finish = this->members_.m_start;
2431
+ this->prot_reset_finish_to_start();
2316
2432
  }
2317
2433
  }
2318
2434
 
@@ -2368,6 +2484,19 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2368
2484
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2369
2485
  private:
2370
2486
 
2487
+ template <class InsertProxy>
2488
+ void priv_assign(size_type n, InsertProxy proxy)
2489
+ {
2490
+ const size_type sz = this->prot_size();
2491
+ this->priv_segmented_proxy_copy_n_and_update(this->begin(), sz < n ? sz : n, proxy);
2492
+ if (n > sz) {
2493
+ this->priv_insert_back_aux_impl(size_type(n - sz), proxy);
2494
+ }
2495
+ else{
2496
+ this->priv_erase_last_n(size_type(sz - n));
2497
+ }
2498
+ }
2499
+
2371
2500
  void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<true> /*steal_resources*/)
2372
2501
  {
2373
2502
  //Destroy objects but retain memory in case x reuses it in the future
@@ -2396,19 +2525,20 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2396
2525
  {
2397
2526
  BOOST_ASSERT(this->cbegin() <= p);
2398
2527
  BOOST_ASSERT(p <= this->cend());
2399
- return static_cast<size_type>(p - this->cbegin());
2528
+ return this->prot_it_to_start_off(p);
2400
2529
  }
2401
2530
 
2402
2531
  void priv_erase_last_n(size_type n)
2403
2532
  {
2404
- if(n == this->size()) {
2405
- this->clear();
2406
- }
2407
- else {
2408
- iterator new_finish = this->members_.m_finish - difference_type(n);
2409
- this->priv_destroy_range(new_finish, this->members_.m_finish);
2410
- this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
2411
- this->members_.m_finish = new_finish;
2533
+ const size_type sz = this->prot_size();
2534
+ BOOST_ASSERT(n <= sz);
2535
+
2536
+ if(sz) {
2537
+ const iterator old_finish = this->prot_finish();
2538
+ const iterator new_finish = old_finish - difference_type(n);
2539
+ this->prot_destroy_range(new_finish, old_finish);
2540
+ this->prot_deallocate_nodes_if_not_reservable(new_finish.get_node() + 1, old_finish.get_node() + 1);
2541
+ this->prot_dec_finish(n);
2412
2542
  }
2413
2543
  }
2414
2544
 
@@ -2429,93 +2559,48 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2429
2559
  }
2430
2560
 
2431
2561
  template <class U>
2432
- iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
2562
+ BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
2433
2563
  {
2434
- BOOST_ASSERT(this->priv_in_range_or_end(p));
2435
- if (p == cbegin()){
2436
- this->push_front(::boost::forward<U>(x));
2437
- return begin();
2438
- }
2439
- else if (p == cend()){
2440
- this->push_back(::boost::forward<U>(x));
2441
- return --end();
2442
- }
2443
- else {
2444
- return priv_insert_aux_impl
2445
- ( p, (size_type)1
2446
- , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2447
- }
2564
+ return this->emplace(p, ::boost::forward<U>(x));
2448
2565
  }
2449
2566
 
2450
2567
  template <class U>
2451
- void priv_push_front(BOOST_FWD_REF(U) x)
2568
+ BOOST_CONTAINER_FORCEINLINE void priv_push_back(BOOST_FWD_REF(U) u)
2452
2569
  {
2453
- if(this->priv_push_front_simple_available()){
2454
- allocator_traits_type::construct
2455
- ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
2456
- this->priv_push_front_simple_commit();
2457
- }
2458
- else{
2459
- priv_insert_aux_impl
2460
- ( this->cbegin(), (size_type)1
2461
- , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2462
- }
2570
+ this->emplace_back(::boost::forward<U>(u));
2463
2571
  }
2464
2572
 
2465
2573
  template <class U>
2466
- void priv_push_back(BOOST_FWD_REF(U) x)
2467
- {
2468
- if(this->priv_push_back_simple_available()){
2469
- allocator_traits_type::construct
2470
- ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
2471
- this->priv_push_back_simple_commit();
2472
- }
2473
- else{
2474
- priv_insert_aux_impl
2475
- ( this->cend(), (size_type)1
2476
- , dtl::get_insert_value_proxy<iterator, ValAllocator>(::boost::forward<U>(x)));
2477
- }
2478
- }
2479
-
2480
- inline bool priv_push_back_simple_available() const
2481
- {
2482
- return this->members_.m_map &&
2483
- (this->members_.m_finish.m_cur != (this->members_.m_finish.get_last() - 1));
2484
- }
2485
-
2486
- inline T *priv_push_back_simple_pos() const
2487
- {
2488
- return boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur);
2489
- }
2490
-
2491
- inline void priv_push_back_simple_commit()
2574
+ BOOST_CONTAINER_FORCEINLINE void priv_push_front(BOOST_FWD_REF(U) u)
2492
2575
  {
2493
- ++this->members_.m_finish.m_cur;
2576
+ this->emplace_front(::boost::forward<U>(u));
2494
2577
  }
2495
2578
 
2496
- inline bool priv_push_front_simple_available() const
2497
- {
2498
- return this->members_.m_map &&
2499
- (this->members_.m_start.m_cur != this->members_.m_start.get_first());
2500
- }
2501
-
2502
- inline T *priv_push_front_simple_pos() const
2503
- { return boost::movelib::to_raw_pointer(this->members_.m_start.m_cur) - 1; }
2504
-
2505
- inline void priv_push_front_simple_commit()
2506
- { --this->members_.m_start.m_cur; }
2507
-
2508
- void priv_destroy_range(iterator p, iterator p2)
2579
+ void prot_destroy_range(iterator start, iterator finish)
2509
2580
  {
2510
- (void)p; (void)p2;
2581
+ (void)start; (void)finish;
2511
2582
  BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
2512
- for(;p != p2; ++p){
2513
- allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
2583
+ const index_pointer start_node = start.get_node();
2584
+ const index_pointer finish_node = finish.get_node();
2585
+
2586
+ //In a sane deque both should be null or non-null
2587
+ BOOST_ASSERT(!start_node == !finish_node);
2588
+ if(start_node){
2589
+ for (index_pointer node = start_node + 1; node < finish_node; ++node) {
2590
+ this->prot_destroy_range(*node, *node + get_block_ssize());
2591
+ }
2592
+
2593
+ if (start_node != finish_node) {
2594
+ this->prot_destroy_range(start.get_cur(), start.get_last());
2595
+ this->prot_destroy_range(finish.get_first(), finish.get_cur());
2596
+ }
2597
+ else
2598
+ this->prot_destroy_range(start.get_cur(), finish.get_cur());
2514
2599
  }
2515
2600
  }
2516
2601
  }
2517
2602
 
2518
- void priv_destroy_range(pointer p, pointer p2)
2603
+ void prot_destroy_range(pointer p, pointer p2)
2519
2604
  {
2520
2605
  (void)p; (void)p2;
2521
2606
  BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
@@ -2526,187 +2611,364 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2526
2611
  }
2527
2612
 
2528
2613
  template<class InsertProxy>
2529
- iterator priv_insert_middle_aux_impl(const_iterator p, const size_type elemsbefore, const size_type length, const size_type n, InsertProxy proxy)
2614
+ iterator priv_insert_middle_aux_impl(const size_type elemsbefore, const size_type n, InsertProxy proxy)
2530
2615
  {
2531
- if (!this->members_.m_map) {
2532
- this->priv_initialize_map(0);
2533
- p = this->cbegin();
2534
- }
2535
-
2536
- iterator pos(p.unconst());
2537
- const size_type pos_n = size_type(p - this->cbegin());
2616
+ typedef dtl::bool_<dtl::is_single_value_proxy<InsertProxy>::value> single_t;
2617
+ BOOST_ASSERT(!single_t::value || n == 1);
2538
2618
 
2619
+ const size_type length = this->prot_size();
2539
2620
  if (elemsbefore < length / 2) {
2540
- const iterator new_start = this->priv_reserve_elements_at_front(n);
2541
- const iterator old_start = this->members_.m_start;
2542
- pos = this->members_.m_start + difference_type(elemsbefore);
2543
- if (elemsbefore >= n) {
2544
- const iterator start_n = this->members_.m_start + difference_type(n);
2621
+ this->priv_reserve_elements_at_front(n);
2622
+ const iterator old_start = this->prot_start();
2623
+ iterator new_start = old_start;
2624
+ priv_itsub(new_start, n, single_t());
2625
+
2626
+ BOOST_ASSERT(!single_t::value || elemsbefore >= 1);
2627
+
2628
+ if(single_t::value || elemsbefore >= n) {
2629
+ iterator start_n = old_start;
2630
+ priv_itadd(start_n, n, single_t());
2545
2631
  BOOST_CONTAINER_TRY {
2546
- ::boost::container::uninitialized_move_alloc
2547
- (this->alloc(), this->members_.m_start, start_n, new_start);
2632
+ this->priv_segmented_uninitialized_move_alloc_n(old_start, n, new_start, single_t());
2548
2633
  }
2549
2634
  BOOST_CONTAINER_CATCH(...) {
2550
- this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
2635
+ this->prot_deallocate_nodes_if_not_reservable(new_start.m_node, old_start.m_node);
2551
2636
  BOOST_CONTAINER_RETHROW
2552
2637
  }
2553
2638
  BOOST_CONTAINER_CATCH_END
2554
- this->members_.m_start = new_start;
2555
- boost::container::move(start_n, pos, old_start);
2556
- proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n);
2639
+
2640
+ this->prot_dec_start(n);
2641
+ iterator p = this->priv_segmented_move_n(start_n, size_type(elemsbefore - n), old_start);
2642
+ this->priv_segmented_proxy_copy_n_and_update(p, n, proxy);
2643
+ return p;
2557
2644
  }
2558
2645
  else {
2559
- const size_type mid_count = n - elemsbefore;
2560
- const iterator mid_start = old_start - difference_type(mid_count);
2646
+ const size_type mid_count = size_type(n - elemsbefore);
2647
+ iterator mid_start = old_start - difference_type(mid_count);
2648
+
2561
2649
  BOOST_CONTAINER_TRY {
2562
- proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
2563
- this->members_.m_start = mid_start;
2564
- ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
2650
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(mid_start, mid_count, proxy);
2651
+ this->prot_dec_start(mid_count);
2652
+ this->priv_segmented_uninitialized_move_alloc_n(old_start, elemsbefore, new_start);
2565
2653
  }
2566
2654
  BOOST_CONTAINER_CATCH(...) {
2567
- this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
2655
+ this->prot_deallocate_nodes_if_not_reservable(new_start.m_node, old_start.get_node());
2568
2656
  BOOST_CONTAINER_RETHROW
2569
2657
  }
2570
2658
  BOOST_CONTAINER_CATCH_END
2571
- this->members_.m_start = new_start;
2572
- proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
2659
+ this->prot_dec_start(size_type(n - mid_count));
2660
+ this->priv_segmented_proxy_copy_n_and_update(old_start, elemsbefore, proxy);
2661
+ return mid_start;
2573
2662
  }
2574
2663
  }
2575
2664
  else {
2576
- const iterator new_finish = this->priv_reserve_elements_at_back(n);
2577
- const iterator old_finish = this->members_.m_finish;
2578
- const size_type elemsafter = length - elemsbefore;
2665
+ this->priv_reserve_elements_at_back(n);
2666
+ const iterator old_finish = this->prot_finish();
2667
+ const size_type elemsafter = size_type(length - elemsbefore);
2668
+
2669
+ BOOST_ASSERT(!single_t::value || elemsafter >= 1);
2579
2670
 
2580
- pos = old_finish - difference_type(elemsafter);
2581
- if (elemsafter >= n) {
2582
- iterator finish_n = old_finish - difference_type(n);
2671
+ if(single_t::value || elemsafter >= n) {
2672
+ iterator finish_n = old_finish;
2673
+ priv_itsub(finish_n, n, single_t());
2583
2674
  BOOST_CONTAINER_TRY {
2584
- ::boost::container::uninitialized_move_alloc(this->alloc(), finish_n, old_finish, old_finish);
2675
+ this->priv_segmented_uninitialized_move_alloc_n(finish_n, n, old_finish, single_t());
2585
2676
  }
2586
2677
  BOOST_CONTAINER_CATCH(...) {
2587
- this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
2678
+ this->prot_deallocate_nodes_if_not_reservable(old_finish.get_node() + 1, (old_finish + difference_type(n)).m_node + 1);
2588
2679
  BOOST_CONTAINER_RETHROW
2589
2680
  }
2590
2681
  BOOST_CONTAINER_CATCH_END
2591
2682
 
2592
- this->members_.m_finish = new_finish;
2593
- boost::container::move_backward(pos, finish_n, old_finish);
2594
- proxy.copy_n_and_update(this->alloc(), pos, n);
2683
+ this->prot_inc_finish(n);
2684
+ const size_type move_n = size_type(elemsafter - n);
2685
+ this->priv_segmented_move_backward_n(finish_n, move_n, old_finish);
2686
+ finish_n -= difference_type(move_n);
2687
+ this->priv_segmented_proxy_copy_n_and_update(finish_n, n, proxy);
2688
+ return finish_n;
2595
2689
  }
2596
2690
  else {
2597
- const size_type raw_gap = n - elemsafter;
2691
+ const size_type raw_gap = size_type(n - elemsafter);
2692
+ iterator pos = old_finish - difference_type(elemsafter);
2693
+
2598
2694
  BOOST_CONTAINER_TRY{
2599
- ::boost::container::uninitialized_move_alloc
2600
- (this->alloc(), pos, old_finish, old_finish + difference_type(raw_gap));
2695
+ this->priv_segmented_uninitialized_move_alloc_n(pos, elemsafter, old_finish + difference_type(raw_gap));
2601
2696
  BOOST_CONTAINER_TRY{
2602
- proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
2603
- proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
2697
+ this->priv_segmented_proxy_copy_n_and_update(pos, elemsafter, proxy);
2698
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(old_finish, raw_gap, proxy);
2604
2699
  }
2605
2700
  BOOST_CONTAINER_CATCH(...) {
2606
- this->priv_destroy_range(old_finish, old_finish + difference_type(elemsafter));
2701
+ this->prot_destroy_range(old_finish, old_finish + difference_type(elemsafter));
2607
2702
  BOOST_CONTAINER_RETHROW
2608
2703
  }
2609
2704
  BOOST_CONTAINER_CATCH_END
2610
2705
  }
2611
2706
  BOOST_CONTAINER_CATCH(...) {
2612
- this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
2707
+ this->prot_deallocate_nodes_if_not_reservable(old_finish.get_node() + 1, (old_finish + difference_type(n)).m_node + 1);
2613
2708
  BOOST_CONTAINER_RETHROW
2614
2709
  }
2615
2710
  BOOST_CONTAINER_CATCH_END
2616
- this->members_.m_finish = new_finish;
2711
+ this->prot_inc_finish(n);
2712
+ return pos;
2617
2713
  }
2618
2714
  }
2619
- return this->begin() + difference_type(pos_n);
2620
2715
  }
2621
2716
 
2622
2717
  template<class InsertProxy>
2623
2718
  iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
2624
2719
  {
2625
- iterator pos(p.unconst());
2626
- const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
2627
- const size_type length = this->size();
2720
+ const size_type elemsbefore = this->prot_it_to_start_off(p);
2628
2721
 
2629
2722
  if (!elemsbefore) {
2630
2723
  return this->priv_insert_front_aux_impl(n, proxy);
2631
2724
  }
2632
- else if (elemsbefore == length) {
2725
+ else if (elemsbefore == this->prot_size()) {
2633
2726
  return this->priv_insert_back_aux_impl(n, proxy);
2634
2727
  }
2635
2728
  else {
2636
- return this->priv_insert_middle_aux_impl(p, elemsbefore, length, n, proxy);
2729
+ return this->priv_insert_middle_aux_impl(elemsbefore, n, proxy);
2637
2730
  }
2638
2731
  }
2639
2732
 
2640
2733
  template <class InsertProxy>
2641
- iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
2734
+ void priv_segmented_proxy_uninitialized_copy_n_and_update(const iterator first, size_type n, InsertProxy &proxy)
2642
2735
  {
2643
- if(!this->members_.m_map){
2644
- this->priv_initialize_map(0);
2736
+ BOOST_IF_CONSTEXPR (dtl::is_single_value_proxy<InsertProxy>::value) {
2737
+ (void)n;
2738
+ proxy.uninitialized_copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(first.get_cur()), 1u);
2645
2739
  }
2740
+ else if (BOOST_LIKELY(n != 0)){ //We might initialize an empty range and current_node might be null
2741
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
2646
2742
 
2647
- iterator new_finish = this->priv_reserve_elements_at_back(n);
2648
- BOOST_CONTAINER_TRY{
2649
- proxy.uninitialized_copy_n_and_update(this->alloc(), this->members_.m_finish, n);
2650
- }
2651
- BOOST_CONTAINER_CATCH(...) {
2652
- this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
2653
- BOOST_CONTAINER_RETHROW
2743
+ index_pointer current_node = first.get_node();
2744
+
2745
+ BOOST_CONTAINER_TRY{
2746
+ const pointer cur = first.get_cur();
2747
+ const size_type block = size_type(block_size - size_type(cur - *current_node));
2748
+ size_type cnt = n < block ? n: block;
2749
+ proxy.uninitialized_copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt);
2750
+ n = size_type(n - cnt);
2751
+
2752
+ while (n) {
2753
+ ++current_node;
2754
+ cnt = n < block_size ? n: block_size;
2755
+ proxy.uninitialized_copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt);
2756
+ n = size_type(n - cnt);
2757
+ }
2758
+ }
2759
+ BOOST_CONTAINER_CATCH(...) {
2760
+ this->prot_destroy_range(first, iterator(*current_node, current_node));
2761
+ BOOST_CONTAINER_RETHROW
2762
+ }
2763
+ BOOST_CONTAINER_CATCH_END
2654
2764
  }
2655
- BOOST_CONTAINER_CATCH_END
2656
- this->members_.m_finish = new_finish;
2657
- return iterator(this->members_.m_finish - difference_type(n));
2658
2765
  }
2659
2766
 
2767
+
2660
2768
  template <class InsertProxy>
2661
- iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
2769
+ void priv_segmented_proxy_copy_n_and_update(const iterator first, size_type n, InsertProxy &proxy)
2662
2770
  {
2663
- if(!this->members_.m_map){
2664
- this->priv_initialize_map(0);
2771
+ BOOST_IF_CONSTEXPR (dtl::is_single_value_proxy<InsertProxy>::value) {
2772
+ (void)n;
2773
+ proxy.copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(first.get_cur()), 1u);
2665
2774
  }
2775
+ else if (BOOST_LIKELY(n != 0)){ //We might assign an empty range in a default constructed deque
2776
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
2666
2777
 
2667
- iterator new_start = this->priv_reserve_elements_at_front(n);
2778
+ index_pointer current_node = first.get_node();
2779
+
2780
+ const pointer cur = first.get_cur();
2781
+ const size_type block = size_type(block_size - size_type(cur - *current_node));
2782
+ size_type cnt = n < block ? n: block;
2783
+ proxy.copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt);
2784
+ n = size_type(n - cnt);
2785
+
2786
+ while (n) {
2787
+ ++current_node;
2788
+ cnt = n < block_size ? n: block_size;
2789
+ proxy.copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt);
2790
+ n = size_type(n - cnt);
2791
+ }
2792
+ }
2793
+ }
2794
+
2795
+ template <class InsertProxy>
2796
+ void priv_insert_segmented_uninitialized_copy_n_and_update(const iterator first, size_type n, InsertProxy proxy)
2797
+ {
2668
2798
  BOOST_CONTAINER_TRY{
2669
- proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
2799
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(first, n, proxy);
2670
2800
  }
2671
2801
  BOOST_CONTAINER_CATCH(...) {
2672
- this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
2802
+ this->prot_deallocate_nodes_if_not_reservable(first.get_node() + 1, (first+difference_type(n)).get_node() + 1);
2673
2803
  BOOST_CONTAINER_RETHROW
2674
2804
  }
2675
2805
  BOOST_CONTAINER_CATCH_END
2806
+ }
2676
2807
 
2677
- this->members_.m_start = new_start;
2678
- return new_start;
2808
+ template<class It>
2809
+ static BOOST_CONTAINER_FORCEINLINE void priv_itadd(It &it, size_type, dtl::bool_<true> /*single element*/)
2810
+ { ++it; }
2811
+
2812
+ template<class It>
2813
+ static BOOST_CONTAINER_FORCEINLINE void priv_itadd(It &it, size_type n, dtl::bool_<false> /*!single element*/)
2814
+ { it += difference_type(n); }
2815
+
2816
+ template<class It>
2817
+ static BOOST_CONTAINER_FORCEINLINE void priv_itsub(It &it, size_type, dtl::bool_<true> /*single element*/)
2818
+ { --it; }
2819
+
2820
+ template<class It>
2821
+ static BOOST_CONTAINER_FORCEINLINE void priv_itsub(It &it, size_type n, dtl::bool_<false> /*!single element*/)
2822
+ { it -= difference_type(n); }
2823
+
2824
+ void priv_segmented_uninitialized_move_alloc_n(iterator first, size_type n, iterator dest, dtl::bool_<true> /*single element*/)
2825
+ {
2826
+ BOOST_ASSERT(n == 1); (void)n;
2827
+ allocator_traits_type::construct
2828
+ ( this->alloc()
2829
+ , boost::movelib::to_raw_pointer(dest.get_cur())
2830
+ , boost::move(*first));
2679
2831
  }
2680
2832
 
2681
- inline iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
2833
+ void priv_segmented_uninitialized_move_alloc_n(iterator first, size_type n, iterator dest, dtl::bool_<false> /*!single element*/)
2682
2834
  {
2683
- return this->insert(pos, c_it(x, n), c_it());
2835
+ if (BOOST_LIKELY(n != 0)) { //Check for empty range, current_node might be null
2836
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
2837
+
2838
+ index_pointer current_node = first.get_node();
2839
+
2840
+ BOOST_CONTAINER_TRY{
2841
+ const pointer cur = first.get_cur();
2842
+ const size_type block = size_type(block_size - size_type(cur - *current_node));
2843
+ size_type cnt = n < block ? n: block;
2844
+ dest = ::boost::container::uninitialized_move_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt, dest);
2845
+ n = size_type(n - cnt);
2846
+
2847
+ while (n) {
2848
+ ++current_node;
2849
+ cnt = n < block_size ? n: block_size;
2850
+ dest = ::boost::container::uninitialized_move_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt, dest);
2851
+ n = size_type(n - cnt);
2852
+ }
2853
+ }
2854
+ BOOST_CONTAINER_CATCH(...) {
2855
+ this->prot_destroy_range(first, iterator(*current_node, current_node));
2856
+ BOOST_CONTAINER_RETHROW
2857
+ }
2858
+ BOOST_CONTAINER_CATCH_END
2859
+ }
2684
2860
  }
2685
2861
 
2686
- // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
2687
- // but none of the deque's elements have yet been constructed.
2688
- void priv_fill_initialize(const value_type& value)
2862
+ BOOST_CONTAINER_FORCEINLINE void priv_segmented_uninitialized_move_alloc_n(iterator first, size_type n, iterator dest)
2689
2863
  {
2690
- index_pointer cur = this->members_.m_start.m_node;
2691
- BOOST_CONTAINER_TRY {
2692
- for ( ; cur < this->members_.m_finish.m_node; ++cur){
2693
- boost::container::uninitialized_fill_alloc
2694
- (this->alloc(), *cur, *cur + get_block_ssize(), value);
2864
+ this->priv_segmented_uninitialized_move_alloc_n(first, n, dest, dtl::bool_<false>());
2865
+ }
2866
+
2867
+ void priv_segmented_uninitialized_copy_alloc_n(const_iterator first, size_type n, iterator dest)
2868
+ {
2869
+ if (BOOST_LIKELY(n != 0)) { //We might initialize an empty range and current_node might be null
2870
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
2871
+
2872
+ index_pointer current_node = first.get_node();
2873
+
2874
+ BOOST_CONTAINER_TRY{
2875
+ const pointer cur = first.get_cur();
2876
+ const size_type block = size_type(block_size - size_type(cur - *current_node));
2877
+ size_type cnt = n < block ? n: block;
2878
+ dest = ::boost::container::uninitialized_copy_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt, dest);
2879
+ n = size_type(n - cnt);
2880
+
2881
+ while (n) {
2882
+ ++current_node;
2883
+ cnt = n < block_size ? n: block_size;
2884
+ dest = ::boost::container::uninitialized_copy_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt, dest);
2885
+ n = size_type(n - cnt);
2886
+ }
2887
+ }
2888
+ BOOST_CONTAINER_CATCH(...) {
2889
+ this->prot_destroy_range(first.unconst(), iterator(*current_node, current_node));
2890
+ BOOST_CONTAINER_RETHROW
2695
2891
  }
2696
- boost::container::uninitialized_fill_alloc
2697
- (this->alloc(), this->members_.m_finish.get_first(), this->members_.m_finish.m_cur, value);
2892
+ BOOST_CONTAINER_CATCH_END
2698
2893
  }
2699
- BOOST_CONTAINER_CATCH(...){
2700
- this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur, get_block_size()));
2701
- BOOST_CONTAINER_RETHROW
2894
+ }
2895
+
2896
+ static iterator priv_segmented_move_n(const_iterator first, size_type n, iterator dest)
2897
+ {
2898
+ index_pointer current_node = first.get_node();
2899
+ BOOST_ASSERT(current_node != index_pointer());
2900
+
2901
+ const pointer cur = first.get_cur();
2902
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
2903
+
2904
+ const size_type block = size_type(block_size - size_type(cur - *current_node));
2905
+ size_type cnt = n < block ? n: block;
2906
+ dest = ::boost::container::move_n(boost::movelib::to_raw_pointer(cur), cnt, dest);
2907
+ n = size_type(n - cnt);
2908
+
2909
+ while (n) {
2910
+ ++current_node;
2911
+ cnt = n < block_size ? n: block_size;
2912
+ dest = ::boost::container::move_n(boost::movelib::to_raw_pointer(*current_node), cnt, dest);
2913
+ n = size_type(n - cnt);
2702
2914
  }
2703
- BOOST_CONTAINER_CATCH_END
2915
+ return dest;
2916
+ }
2917
+
2918
+ static iterator priv_segmented_move_backward_n(iterator last, size_type n, iterator dest_last)
2919
+ {
2920
+ index_pointer current_node = last.get_node();
2921
+ BOOST_ASSERT(current_node != index_pointer());
2922
+
2923
+ const pointer cur = last.get_cur();
2924
+ const size_type block = size_type(cur - *current_node);
2925
+ size_type cnt = n < block ? n: block;
2926
+ dest_last = ::boost::container::move_backward_n(boost::movelib::to_raw_pointer(cur), cnt, dest_last);
2927
+ n = size_type(n - cnt);
2928
+
2929
+ BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
2930
+
2931
+ while (n) {
2932
+ --current_node;
2933
+ cnt = n < block_size ? n: block_size;
2934
+ dest_last = ::boost::container::move_backward_n(boost::movelib::to_raw_pointer(*current_node + difference_type(block_size)), cnt, dest_last);
2935
+ n = size_type(n - cnt);
2936
+ }
2937
+ return dest_last;
2938
+ }
2939
+
2940
+ template <class InsertProxy>
2941
+ iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
2942
+ {
2943
+ this->priv_reserve_elements_at_back(n);
2944
+ const iterator old_finish = this->prot_finish();
2945
+ this->priv_insert_segmented_uninitialized_copy_n_and_update(old_finish, n, proxy);
2946
+ this->prot_inc_finish(n);
2947
+ return old_finish;
2948
+ }
2949
+
2950
+ template <class InsertProxy>
2951
+ iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
2952
+ {
2953
+ this->priv_reserve_elements_at_front(n);
2954
+ const iterator old_start = this->prot_start();
2955
+ const iterator new_start = old_start - difference_type(n);
2956
+ this->priv_insert_segmented_uninitialized_copy_n_and_update(new_start, n, proxy);
2957
+ this->prot_dec_start(n);
2958
+ return new_start;
2959
+ }
2960
+
2961
+ // Precondition: this->prot_start() and this->prot_finish() have already been initialized,
2962
+ // but none of the deque's elements have yet been constructed.
2963
+ void priv_fill_initialize(size_type n, const value_type& value)
2964
+ {
2965
+ dtl::insert_n_copies_proxy<ValAllocator> proxy(value);
2966
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
2704
2967
  }
2705
2968
 
2706
2969
  template <class InIt>
2707
2970
  void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type* =0)
2708
2971
  {
2709
- this->priv_initialize_map(0);
2710
2972
  BOOST_CONTAINER_TRY {
2711
2973
  for ( ; first != last; ++first)
2712
2974
  this->emplace_back(*first);
@@ -2721,136 +2983,78 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2721
2983
  template <class FwdIt>
2722
2984
  void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type* =0)
2723
2985
  {
2724
- size_type n = 0;
2725
- n = boost::container::iterator_udistance(first, last);
2726
- this->priv_initialize_map(n);
2727
-
2728
- index_pointer cur_node = this->members_.m_start.m_node;
2729
- BOOST_CONTAINER_TRY {
2730
- for (; cur_node < this->members_.m_finish.m_node; ++cur_node) {
2731
- FwdIt mid = first;
2732
- boost::container::iterator_uadvance(mid, get_block_size());
2733
- ::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
2734
- first = mid;
2735
- }
2736
- ::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.get_first());
2737
- }
2738
- BOOST_CONTAINER_CATCH(...){
2739
- this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node, get_block_size()));
2740
- BOOST_CONTAINER_RETHROW
2986
+ typedef typename iter_size<FwdIt>::type it_size_type;
2987
+ const it_size_type sz = boost::container::iterator_udistance(first, last);
2988
+ if (BOOST_UNLIKELY(sz > size_type(-1))){
2989
+ boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
2741
2990
  }
2742
- BOOST_CONTAINER_CATCH_END
2991
+ const size_type n = static_cast<size_type>(sz);
2992
+ this->prot_initialize_map_and_nodes(n);
2993
+
2994
+ dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
2995
+ this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
2743
2996
  }
2744
2997
 
2745
- // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.get_first().
2998
+ // Called only if this->prot_finish_cur() == this->prot_finish().get_first().
2746
2999
  void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
2747
3000
  {
2748
- this->priv_deallocate_node(this->members_.m_finish.get_first());
2749
- this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1, get_block_size());
2750
- this->members_.m_finish.m_cur = this->members_.m_finish.get_last() - 1;
3001
+ index_pointer ip = this->prot_finish_node();
3002
+ this->prot_deallocate_node_if_not_reservable(*ip);
3003
+ this->prot_dec_finish();
3004
+ --ip;
2751
3005
  allocator_traits_type::destroy
2752
3006
  ( this->alloc()
2753
- , boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
3007
+ , boost::movelib::to_raw_pointer(this->prot_node_last(ip))
2754
3008
  );
2755
3009
  }
2756
3010
 
2757
- // Called only if this->members_.m_start.m_cur == this->members_.m_start.get_last() - 1. Note that
3011
+ // Called only if this->prot_start_cur() == this->prot_start().get_last() - 1. Note that
2758
3012
  // if the deque has at least one element (a precondition for this member
2759
- // function), and if this->members_.m_start.m_cur == this->members_.m_start.get_last(), then the deque
3013
+ // function), and if this->prot_start_cur() == this->prot_start().get_last(), then the deque
2760
3014
  // must have at least two nodes.
2761
3015
  void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
2762
3016
  {
3017
+ const index_pointer ip = this->prot_start_node();
2763
3018
  allocator_traits_type::destroy
2764
3019
  ( this->alloc()
2765
- , boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
3020
+ , boost::movelib::to_raw_pointer(this->prot_node_last(ip))
2766
3021
  );
2767
- this->priv_deallocate_node(this->members_.m_start.get_first());
2768
- this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1, get_block_size());
2769
- this->members_.m_start.m_cur = this->members_.m_start.get_first();
3022
+ this->prot_deallocate_node_if_not_reservable(*ip);
3023
+ this->prot_inc_start();
2770
3024
  }
2771
3025
 
2772
- iterator priv_reserve_elements_at_front(size_type n)
3026
+ void priv_reserve_elements_at_front(size_type n)
2773
3027
  {
2774
- size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.get_first());
2775
- if (n > vacancies){
2776
- size_type new_elems = n-vacancies;
2777
- size_type new_nodes = (new_elems + get_block_size() - 1u) / get_block_size();
2778
- size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
2779
- if (new_nodes > s){
2780
- this->priv_reallocate_map(new_nodes, true);
2781
- }
2782
- size_type i = 1;
2783
- BOOST_CONTAINER_TRY {
2784
- for (; i <= new_nodes; ++i)
2785
- *(this->members_.m_start.m_node - difference_type(i)) = this->priv_allocate_node();
3028
+ const size_type vacancies = this->prot_front_free_capacity();
3029
+ typedef dtl::bool_<is_reservable> res_t;
3030
+
3031
+ if (n > vacancies){ //n == 0 handled in the else part
3032
+ if(this->members_.m_map){
3033
+ this->prot_reallocate_map_and_nodes(res_t(), size_type(n - vacancies), true);
2786
3034
  }
2787
- BOOST_CONTAINER_CATCH(...) {
2788
- for (size_type j = 1; j < i; ++j)
2789
- this->priv_deallocate_node(*(this->members_.m_start.m_node - difference_type(j)));
2790
- BOOST_CONTAINER_RETHROW
3035
+ else {
3036
+ this->prot_initialize_map_and_nodes(n);
3037
+ this->prot_reset_start_to_finish();
2791
3038
  }
2792
- BOOST_CONTAINER_CATCH_END
2793
3039
  }
2794
- return this->members_.m_start - difference_type(n);
2795
3040
  }
2796
3041
 
2797
- iterator priv_reserve_elements_at_back(size_type n)
3042
+ void priv_reserve_elements_at_back(size_type n)
2798
3043
  {
2799
- size_type vacancies = size_type(this->members_.m_finish.get_last() - this->members_.m_finish.m_cur - 1);
2800
- if (n > vacancies){
2801
- size_type new_elems = size_type(n - vacancies);
2802
- size_type new_nodes = size_type(new_elems + get_block_size() - 1u)/get_block_size();
2803
- size_type s = (size_type)(this->members_.m_map_size - size_type(this->members_.m_finish.m_node - this->members_.m_map));
2804
- if (new_nodes + 1 > s){
2805
- this->priv_reallocate_map(new_nodes, false);
2806
- }
2807
- size_type i = 1;
2808
- BOOST_CONTAINER_TRY {
2809
- for (; i <= new_nodes; ++i)
2810
- *(this->members_.m_finish.m_node + difference_type(i)) = this->priv_allocate_node();
3044
+ const size_type vacancies = this->prot_back_free_capacity();
3045
+ typedef dtl::bool_<is_reservable> res_t;
3046
+
3047
+ if (n > vacancies){ //n == 0 handled in the else part
3048
+ if(this->members_.m_map){
3049
+ this->prot_reallocate_map_and_nodes(res_t(), size_type(n - vacancies), false);
2811
3050
  }
2812
- BOOST_CONTAINER_CATCH(...) {
2813
- for (size_type j = 1; j < i; ++j)
2814
- this->priv_deallocate_node(*(this->members_.m_finish.m_node + difference_type(j)));
2815
- BOOST_CONTAINER_RETHROW
3051
+ else{
3052
+ this->prot_initialize_map_and_nodes(n);
3053
+ this->prot_reset_finish_to_start();
2816
3054
  }
2817
- BOOST_CONTAINER_CATCH_END
2818
3055
  }
2819
- return this->members_.m_finish + difference_type(n);
2820
3056
  }
2821
3057
 
2822
- void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
2823
- {
2824
- size_type old_num_nodes = size_type(this->members_.m_finish.m_node - this->members_.m_start.m_node + 1);
2825
- size_type new_num_nodes = old_num_nodes + nodes_to_add;
2826
-
2827
- index_pointer new_nstart;
2828
- if (this->members_.m_map_size > 2 * new_num_nodes) {
2829
- new_nstart = this->members_.m_map + difference_type(this->members_.m_map_size - new_num_nodes) / 2
2830
- + difference_type(add_at_front ? nodes_to_add : 0u);
2831
- if (new_nstart < this->members_.m_start.m_node)
2832
- boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
2833
- else
2834
- boost::container::move_backward
2835
- (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + difference_type(old_num_nodes));
2836
- }
2837
- else {
2838
- size_type new_map_size =
2839
- this->members_.m_map_size + dtl::max_value(this->members_.m_map_size, nodes_to_add) + 2;
2840
-
2841
- index_pointer new_map = this->priv_allocate_map(new_map_size);
2842
- new_nstart = new_map + difference_type(new_map_size - new_num_nodes) / 2
2843
- + difference_type(add_at_front ? nodes_to_add : 0u);
2844
- boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
2845
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
2846
-
2847
- this->members_.m_map = new_map;
2848
- this->members_.m_map_size = new_map_size;
2849
- }
2850
-
2851
- this->members_.m_start.priv_set_node(new_nstart, get_block_size());
2852
- this->members_.m_finish.priv_set_node(new_nstart + difference_type(old_num_nodes - 1u), get_block_size());
2853
- }
2854
3058
  #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2855
3059
  };
2856
3060
 
@@ -2861,6 +3065,28 @@ template <typename InputIterator, typename Allocator>
2861
3065
  deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
2862
3066
  #endif
2863
3067
 
3068
+ //! <b>Effects</b>: Erases all elements that compare equal to v from the container c.
3069
+ //!
3070
+ //! <b>Complexity</b>: Linear.
3071
+ template <class T, class A, class O, class U>
3072
+ inline typename deque<T, A, O>::size_type erase(deque<T, A, O>& c, const U& v)
3073
+ {
3074
+ typename deque<T, A, O>::size_type old_size = c.size();
3075
+ c.erase(boost::container::remove(c.begin(), c.end(), v), c.end());
3076
+ return old_size - c.size();
3077
+ }
3078
+
3079
+ //! <b>Effects</b>: Erases all elements that satisfy the predicate pred from the container c.
3080
+ //!
3081
+ //! <b>Complexity</b>: Linear.
3082
+ template <class T, class A, class O, class Pred>
3083
+ inline typename deque<T, A, O>::size_type erase_if(deque<T, A, O>& c, Pred pred)
3084
+ {
3085
+ typename deque<T, A, O>::size_type old_size = c.size();
3086
+ c.erase(boost::container::remove_if(c.begin(), c.end(), pred), c.end());
3087
+ return old_size - c.size();
3088
+ }
3089
+
2864
3090
  } //namespace container
2865
3091
  } //namespace boost
2866
3092