passenger 6.0.16 → 6.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (286) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +22 -1
  3. data/build/integration_tests.rb +6 -6
  4. data/build/ruby_tests.rb +1 -1
  5. data/build/test_basics.rb +0 -1
  6. data/src/agent/Core/Config.h +1 -1
  7. data/src/agent/Core/Controller/Config.h +1 -1
  8. data/src/agent/Core/SpawningKit/PipeWatcher.h +18 -3
  9. data/src/agent/Watchdog/Config.h +1 -1
  10. data/src/cxx_supportlib/Constants.h +1 -1
  11. data/src/cxx_supportlib/vendor-modified/boost/align/aligned_alloc.hpp +1 -1
  12. data/src/cxx_supportlib/vendor-modified/boost/array.hpp +1 -1
  13. data/src/cxx_supportlib/vendor-modified/boost/asio/any_completion_executor.hpp +344 -0
  14. data/src/cxx_supportlib/vendor-modified/boost/asio/any_completion_handler.hpp +686 -0
  15. data/src/cxx_supportlib/vendor-modified/boost/asio/any_io_executor.hpp +56 -0
  16. data/src/cxx_supportlib/vendor-modified/boost/asio/associated_allocator.hpp +81 -25
  17. data/src/cxx_supportlib/vendor-modified/boost/asio/associated_cancellation_slot.hpp +68 -8
  18. data/src/cxx_supportlib/vendor-modified/boost/asio/associated_executor.hpp +46 -11
  19. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_datagram_socket.hpp +4 -4
  20. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_deadline_timer.hpp +2 -2
  21. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_file.hpp +1 -1
  22. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_random_access_file.hpp +2 -2
  23. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_raw_socket.hpp +4 -4
  24. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_readable_pipe.hpp +2 -2
  25. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_seq_packet_socket.hpp +2 -2
  26. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_serial_port.hpp +3 -3
  27. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_signal_set.hpp +2 -2
  28. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket.hpp +3 -3
  29. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_acceptor.hpp +4 -4
  30. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_stream_file.hpp +2 -2
  31. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_stream_socket.hpp +2 -2
  32. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_waitable_timer.hpp +2 -2
  33. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_writable_pipe.hpp +2 -2
  34. data/src/cxx_supportlib/vendor-modified/boost/asio/bind_allocator.hpp +13 -3
  35. data/src/cxx_supportlib/vendor-modified/boost/asio/bind_cancellation_slot.hpp +14 -3
  36. data/src/cxx_supportlib/vendor-modified/boost/asio/bind_executor.hpp +13 -3
  37. data/src/cxx_supportlib/vendor-modified/boost/asio/compose.hpp +30 -305
  38. data/src/cxx_supportlib/vendor-modified/boost/asio/consign.hpp +90 -0
  39. data/src/cxx_supportlib/vendor-modified/boost/asio/defer.hpp +17 -18
  40. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/bind_handler.hpp +98 -24
  41. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/composed_work.hpp +330 -0
  42. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/config.hpp +81 -15
  43. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_alloc_helpers.hpp +4 -4
  44. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_work.hpp +19 -11
  45. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/descriptor_ops.ipp +37 -0
  46. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/handler_tracking.ipp +3 -1
  47. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/select_reactor.ipp +1 -1
  48. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/socket_ops.ipp +10 -2
  49. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_executor_service.hpp +14 -1
  50. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/memory.hpp +18 -0
  51. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/utility.hpp +1 -2
  52. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/work_dispatcher.hpp +7 -3
  53. data/src/cxx_supportlib/vendor-modified/boost/asio/dispatch.hpp +4 -14
  54. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/allocator.hpp +22 -3
  55. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/any_executor.hpp +447 -142
  56. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/blocking.hpp +57 -8
  57. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/blocking_adaptation.hpp +51 -6
  58. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/bulk_execute.hpp +5 -0
  59. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/bulk_guarantee.hpp +41 -4
  60. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/connect.hpp +5 -0
  61. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/context.hpp +13 -2
  62. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/context_as.hpp +13 -2
  63. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/as_operation.hpp +4 -0
  64. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/execute.hpp +9 -2
  65. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/executor.hpp +11 -1
  66. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/mapping.hpp +52 -8
  67. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/occupancy.hpp +13 -2
  68. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/operation_state.hpp +5 -0
  69. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/outstanding_work.hpp +39 -6
  70. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/receiver.hpp +5 -0
  71. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/relationship.hpp +39 -6
  72. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/schedule.hpp +5 -0
  73. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/scheduler.hpp +5 -0
  74. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/sender.hpp +5 -0
  75. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/set_done.hpp +5 -0
  76. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/set_error.hpp +5 -0
  77. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/set_value.hpp +5 -0
  78. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/start.hpp +5 -0
  79. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/submit.hpp +5 -0
  80. data/src/cxx_supportlib/vendor-modified/boost/asio/executor_work_guard.hpp +6 -9
  81. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/basic_channel.hpp +3 -3
  82. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/basic_concurrent_channel.hpp +3 -3
  83. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/channel_traits.hpp +70 -0
  84. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/co_composed.hpp +146 -0
  85. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/coro.hpp +35 -5
  86. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_handler.hpp +13 -3
  87. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_operation.hpp +7 -0
  88. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_service.hpp +180 -0
  89. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/coro_completion_handler.hpp +171 -0
  90. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/coro_promise_allocator.hpp +89 -66
  91. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/partial_promise.hpp +66 -45
  92. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/as_single.hpp +13 -3
  93. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/co_composed.hpp +1134 -0
  94. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/coro.hpp +130 -106
  95. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/parallel_group.hpp +377 -3
  96. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/promise.hpp +168 -29
  97. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/use_coro.hpp +149 -203
  98. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/use_promise.hpp +68 -0
  99. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/parallel_group.hpp +256 -0
  100. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/promise.hpp +76 -80
  101. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/use_coro.hpp +40 -14
  102. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/use_promise.hpp +113 -0
  103. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/any_completion_executor.ipp +132 -0
  104. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/any_io_executor.ipp +12 -0
  105. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/append.hpp +12 -3
  106. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/as_tuple.hpp +12 -3
  107. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/buffered_read_stream.hpp +25 -6
  108. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/buffered_write_stream.hpp +25 -6
  109. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/co_spawn.hpp +34 -45
  110. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/connect.hpp +28 -6
  111. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/consign.hpp +204 -0
  112. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/defer.hpp +33 -1
  113. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/deferred.hpp +13 -3
  114. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/dispatch.hpp +21 -9
  115. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/handler_alloc_hook.ipp +1 -1
  116. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/post.hpp +33 -1
  117. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/prepend.hpp +12 -3
  118. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read.hpp +40 -9
  119. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read_at.hpp +27 -6
  120. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read_until.hpp +104 -24
  121. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/redirect_error.hpp +12 -3
  122. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/spawn.hpp +70 -15
  123. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/src.hpp +1 -0
  124. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/use_future.hpp +25 -0
  125. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/write.hpp +38 -30
  126. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/write_at.hpp +27 -6
  127. data/src/cxx_supportlib/vendor-modified/boost/asio/io_context.hpp +0 -13
  128. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/network_v4.ipp +3 -1
  129. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/network_v6.ipp +3 -1
  130. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/basic_descriptor.hpp +2 -2
  131. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/basic_stream_descriptor.hpp +2 -2
  132. data/src/cxx_supportlib/vendor-modified/boost/asio/post.hpp +17 -18
  133. data/src/cxx_supportlib/vendor-modified/boost/asio/spawn.hpp +3 -1
  134. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/io.hpp +13 -3
  135. data/src/cxx_supportlib/vendor-modified/boost/asio/strand.hpp +11 -7
  136. data/src/cxx_supportlib/vendor-modified/boost/asio/system_executor.hpp +0 -13
  137. data/src/cxx_supportlib/vendor-modified/boost/asio/thread_pool.hpp +23 -18
  138. data/src/cxx_supportlib/vendor-modified/boost/asio/version.hpp +1 -1
  139. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_object_handle.hpp +2 -2
  140. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_overlapped_handle.hpp +1 -1
  141. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_random_access_handle.hpp +2 -2
  142. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_stream_handle.hpp +2 -2
  143. data/src/cxx_supportlib/vendor-modified/boost/asio.hpp +4 -0
  144. data/src/cxx_supportlib/vendor-modified/boost/bind/bind.hpp +1 -1
  145. data/src/cxx_supportlib/vendor-modified/boost/chrono/config.hpp +1 -0
  146. data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/inlined/mac/chrono.hpp +4 -4
  147. data/src/cxx_supportlib/vendor-modified/boost/chrono/detail/scan_keyword.hpp +4 -2
  148. data/src/cxx_supportlib/vendor-modified/boost/chrono/duration.hpp +2 -2
  149. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_io.hpp +3 -3
  150. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_put.hpp +5 -5
  151. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_units.hpp +2 -2
  152. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/time_point_io.hpp +2 -2
  153. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/utility/ios_base_state_ptr.hpp +7 -7
  154. data/src/cxx_supportlib/vendor-modified/boost/chrono/time_point.hpp +1 -1
  155. data/src/cxx_supportlib/vendor-modified/boost/circular_buffer/details.hpp +5 -1
  156. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang.hpp +10 -3
  157. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang_version.hpp +9 -3
  158. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/gcc.hpp +9 -3
  159. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/sunpro_cc.hpp +6 -0
  160. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/visualc.hpp +8 -0
  161. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/xlcpp.hpp +4 -0
  162. data/src/cxx_supportlib/vendor-modified/boost/config/detail/suffix.hpp +33 -0
  163. data/src/cxx_supportlib/vendor-modified/boost/config/header_deprecated.hpp +1 -1
  164. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcpp.hpp +9 -0
  165. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libstdcpp3.hpp +4 -2
  166. data/src/cxx_supportlib/vendor-modified/boost/container/allocator.hpp +1 -1
  167. data/src/cxx_supportlib/vendor-modified/boost/container/container_fwd.hpp +29 -0
  168. data/src/cxx_supportlib/vendor-modified/boost/container/deque.hpp +13 -13
  169. data/src/cxx_supportlib/vendor-modified/boost/container/detail/advanced_insert_int.hpp +80 -95
  170. data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_begin.hpp +10 -0
  171. data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_end.hpp +3 -0
  172. data/src/cxx_supportlib/vendor-modified/boost/container/detail/copy_move_algo.hpp +738 -34
  173. data/src/cxx_supportlib/vendor-modified/boost/container/detail/destroyers.hpp +38 -10
  174. data/src/cxx_supportlib/vendor-modified/boost/container/detail/flat_tree.hpp +1 -0
  175. data/src/cxx_supportlib/vendor-modified/boost/container/detail/iterator.hpp +2 -0
  176. data/src/cxx_supportlib/vendor-modified/boost/container/detail/workaround.hpp +3 -4
  177. data/src/cxx_supportlib/vendor-modified/boost/container/devector.hpp +1150 -1213
  178. data/src/cxx_supportlib/vendor-modified/boost/container/node_allocator.hpp +1 -1
  179. data/src/cxx_supportlib/vendor-modified/boost/container/options.hpp +104 -12
  180. data/src/cxx_supportlib/vendor-modified/boost/container/stable_vector.hpp +1 -0
  181. data/src/cxx_supportlib/vendor-modified/boost/container/string.hpp +11 -1
  182. data/src/cxx_supportlib/vendor-modified/boost/container/vector.hpp +31 -331
  183. data/src/cxx_supportlib/vendor-modified/boost/container_hash/detail/hash_mix.hpp +113 -0
  184. data/src/cxx_supportlib/vendor-modified/boost/container_hash/detail/hash_range.hpp +173 -0
  185. data/src/cxx_supportlib/vendor-modified/boost/container_hash/detail/hash_tuple.hpp +133 -0
  186. data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash.hpp +461 -566
  187. data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash_fwd.hpp +24 -24
  188. data/src/cxx_supportlib/vendor-modified/boost/container_hash/is_contiguous_range.hpp +91 -0
  189. data/src/cxx_supportlib/vendor-modified/boost/container_hash/is_described_class.hpp +38 -0
  190. data/src/cxx_supportlib/vendor-modified/boost/container_hash/is_range.hpp +73 -0
  191. data/src/cxx_supportlib/vendor-modified/boost/container_hash/is_unordered_range.hpp +39 -0
  192. data/src/cxx_supportlib/vendor-modified/boost/core/bit.hpp +32 -4
  193. data/src/cxx_supportlib/vendor-modified/boost/core/detail/string_view.hpp +16 -0
  194. data/src/cxx_supportlib/vendor-modified/boost/core/empty_value.hpp +16 -16
  195. data/src/cxx_supportlib/vendor-modified/boost/core/fclose_deleter.hpp +46 -0
  196. data/src/cxx_supportlib/vendor-modified/boost/date_time/date.hpp +1 -1
  197. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/formatters.hpp +3 -3
  198. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/formatters_limited.hpp +3 -3
  199. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_date.hpp +12 -13
  200. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/parsers.hpp +2 -2
  201. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian_calendar.ipp +2 -2
  202. data/src/cxx_supportlib/vendor-modified/boost/date_time/iso_format.hpp +13 -13
  203. data/src/cxx_supportlib/vendor-modified/boost/date_time/local_time/local_date_time.hpp +2 -2
  204. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/time_formatters.hpp +4 -4
  205. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/time_formatters_limited.hpp +2 -2
  206. data/src/cxx_supportlib/vendor-modified/boost/date_time/special_values_parser.hpp +1 -1
  207. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_facet.hpp +1 -1
  208. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_parsing.hpp +2 -2
  209. data/src/cxx_supportlib/vendor-modified/boost/describe/bases.hpp +50 -0
  210. data/src/cxx_supportlib/vendor-modified/boost/describe/detail/config.hpp +40 -0
  211. data/src/cxx_supportlib/vendor-modified/boost/describe/detail/cx_streq.hpp +30 -0
  212. data/src/cxx_supportlib/vendor-modified/boost/describe/detail/void_t.hpp +32 -0
  213. data/src/cxx_supportlib/vendor-modified/boost/describe/members.hpp +159 -0
  214. data/src/cxx_supportlib/vendor-modified/boost/describe/modifiers.hpp +33 -0
  215. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree_algorithms.hpp +9 -9
  216. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree_algorithms.hpp +45 -45
  217. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/any_node_and_algorithms.hpp +8 -8
  218. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/bstree_algorithms_base.hpp +37 -38
  219. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/iterator.hpp +16 -0
  220. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/workaround.hpp +1 -1
  221. data/src/cxx_supportlib/vendor-modified/boost/intrusive/hashtable.hpp +145 -90
  222. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pack_options.hpp +2 -0
  223. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree_algorithms.hpp +7 -7
  224. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sgtree_algorithms.hpp +5 -5
  225. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splaytree_algorithms.hpp +11 -9
  226. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap_algorithms.hpp +7 -7
  227. data/src/cxx_supportlib/vendor-modified/boost/iterator/iterator_facade.hpp +106 -25
  228. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical_streams.hpp +1 -1
  229. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_numeric.hpp +8 -5
  230. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_unsigned_converters.hpp +1 -1
  231. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/adaptive_sort_merge.hpp +4 -2
  232. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/pdqsort.hpp +2 -1
  233. data/src/cxx_supportlib/vendor-modified/boost/move/detail/type_traits.hpp +8 -4
  234. data/src/cxx_supportlib/vendor-modified/boost/mp11/bind.hpp +111 -0
  235. data/src/cxx_supportlib/vendor-modified/boost/mp11/version.hpp +1 -1
  236. data/src/cxx_supportlib/vendor-modified/boost/numeric/conversion/detail/int_float_mixture.hpp +5 -5
  237. data/src/cxx_supportlib/vendor-modified/boost/numeric/conversion/detail/sign_mixture.hpp +5 -5
  238. data/src/cxx_supportlib/vendor-modified/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +5 -5
  239. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/variadic/has_opt.hpp +6 -2
  240. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp +11 -2
  241. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/intrusive_ptr.hpp +1 -1
  242. data/src/cxx_supportlib/vendor-modified/boost/system/detail/config.hpp +7 -1
  243. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_category.hpp +2 -2
  244. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_category_impl.hpp +10 -1
  245. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_code.hpp +38 -43
  246. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_condition.hpp +52 -0
  247. data/src/cxx_supportlib/vendor-modified/boost/throw_exception.hpp +1 -1
  248. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/is_function_ptr_helper.hpp +27 -27
  249. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp +27 -27
  250. data/src/cxx_supportlib/vendor-modified/boost/type_traits/intrinsics.hpp +22 -8
  251. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/fca.hpp +37 -7
  252. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/foa.hpp +1921 -0
  253. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/implementation.hpp +66 -82
  254. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/prime_fmod.hpp +6 -0
  255. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/type_traits.hpp +109 -0
  256. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/xmx.hpp +75 -0
  257. data/src/cxx_supportlib/vendor-modified/boost/unordered/hash_traits.hpp +45 -0
  258. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_map.hpp +732 -0
  259. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_map_fwd.hpp +49 -0
  260. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_set.hpp +586 -0
  261. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_set_fwd.hpp +49 -0
  262. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map.hpp +166 -66
  263. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set.hpp +145 -28
  264. data/src/cxx_supportlib/vendor-modified/boost/version.hpp +2 -2
  265. data/src/cxx_supportlib/vendor-modified/websocketpp/websocketpp/common/md5.hpp +1 -1
  266. data/src/ruby_native_extension/extconf.rb +1 -1
  267. data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +1 -1
  268. data/src/ruby_supportlib/phusion_passenger.rb +5 -5
  269. metadata +36 -19
  270. data/src/cxx_supportlib/vendor-modified/boost/align/align.hpp +0 -19
  271. data/src/cxx_supportlib/vendor-modified/boost/align/alignment_of.hpp +0 -54
  272. data/src/cxx_supportlib/vendor-modified/boost/align/alignment_of_forward.hpp +0 -20
  273. data/src/cxx_supportlib/vendor-modified/boost/align/detail/align_cxx11.hpp +0 -21
  274. data/src/cxx_supportlib/vendor-modified/boost/align/detail/aligned_alloc.hpp +0 -52
  275. data/src/cxx_supportlib/vendor-modified/boost/align/detail/alignment_of.hpp +0 -31
  276. data/src/cxx_supportlib/vendor-modified/boost/align/detail/alignment_of_cxx11.hpp +0 -23
  277. data/src/cxx_supportlib/vendor-modified/boost/align/detail/element_type.hpp +0 -91
  278. data/src/cxx_supportlib/vendor-modified/boost/align/detail/integral_constant.hpp +0 -53
  279. data/src/cxx_supportlib/vendor-modified/boost/align/detail/min_size.hpp +0 -26
  280. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/completion_handler_erasure.hpp +0 -196
  281. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/compose.hpp +0 -709
  282. data/src/cxx_supportlib/vendor-modified/boost/container_hash/detail/float_functions.hpp +0 -336
  283. data/src/cxx_supportlib/vendor-modified/boost/container_hash/detail/hash_float.hpp +0 -271
  284. data/src/cxx_supportlib/vendor-modified/boost/container_hash/detail/limits.hpp +0 -62
  285. data/src/cxx_supportlib/vendor-modified/boost/container_hash/extensions.hpp +0 -361
  286. data/src/cxx_supportlib/vendor-modified/boost/detail/container_fwd.hpp +0 -157
@@ -19,7 +19,7 @@
19
19
  #include <cstring> // memcpy
20
20
 
21
21
  #include <boost/assert.hpp>
22
- #include <boost/aligned_storage.hpp>
22
+ #include <boost/type_traits/aligned_storage.hpp>
23
23
 
24
24
  #include <boost/container/detail/copy_move_algo.hpp>
25
25
  #include <boost/container/new_allocator.hpp> //new_allocator
@@ -35,6 +35,7 @@
35
35
  #include <boost/container/detail/min_max.hpp>
36
36
  #include <boost/container/detail/next_capacity.hpp>
37
37
  #include <boost/container/detail/alloc_helpers.hpp>
38
+ #include <boost/container/detail/advanced_insert_int.hpp>
38
39
 
39
40
  // move
40
41
  #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -53,7 +54,7 @@
53
54
 
54
55
  //std
55
56
  #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
56
- #include <initializer_list> //for std::initializer_list
57
+ #include <initializer_list> //for std::initializer_list
57
58
  #endif
58
59
 
59
60
  namespace boost {
@@ -66,33 +67,36 @@ struct growth_factor_60;
66
67
  template<class Options, class AllocatorSizeType>
67
68
  struct get_devector_opt
68
69
  {
69
- typedef devector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
70
- , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
71
- > type;
70
+ typedef devector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
71
+ , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
72
+ , default_if_zero<Options::free_fraction, relocate_on_90::value>::value
73
+ > type;
72
74
  };
73
75
 
74
76
  template<class AllocatorSizeType>
75
77
  struct get_devector_opt<void, AllocatorSizeType>
76
78
  {
77
- typedef vector_opt<growth_factor_60, AllocatorSizeType> type;
79
+ typedef devector_opt< growth_factor_60, AllocatorSizeType, relocate_on_90::value> type;
78
80
  };
79
81
 
80
- #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
82
+ #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
81
83
 
82
84
  struct reserve_only_tag_t {};
85
+ struct reserve_uninitialized_t {};
86
+ struct review_implementation_t {};
87
+
83
88
  //struct unsafe_uninitialized_tag_t {};
84
89
 
85
90
  /**
86
91
  * A vector-like sequence container providing front and back operations
87
- * (e.g: `push_front`/`pop_front`/`push_back`/`pop_back`) with amortized constant complexity
88
- * and unsafe methods geared towards additional performance.
92
+ * (e.g: `push_front`/`pop_front`/`push_back`/`pop_back`) with amortized constant complexity.
89
93
  *
90
94
  * Models the [SequenceContainer], [ReversibleContainer], and [AllocatorAwareContainer] concepts.
91
95
  *
92
96
  * **Requires**:
93
- * - `T` shall be [MoveInsertable] into the devector.
94
- * - `T` shall be [Erasable] from any `devector<T, allocator_type, GP>`.
95
- * - `GrowthFactor`, and `Allocator` must model the concepts with the same names or be void.
97
+ * - `T` shall be [MoveInsertable] into the devector.
98
+ * - `T` shall be [Erasable] from any `devector<T, allocator_type, GP>`.
99
+ * - `GrowthFactor`, and `Allocator` must model the concepts with the same names or be void.
96
100
  *
97
101
  * **Definition**: `T` is `NothrowConstructible` if it's either nothrow move constructible or
98
102
  * nothrow copy constructible.
@@ -108,13 +112,13 @@ struct reserve_only_tag_t {};
108
112
  *
109
113
  * In addition to the exceptions specified in the **Throws** clause, the following operations
110
114
  * of `T` can throw when any of the specified concept is required:
111
- * - [DefaultInsertable][]: Default constructor
112
- * - [MoveInsertable][]: Move constructor
113
- * - [CopyInsertable][]: Copy constructor
114
- * - [DefaultConstructible][]: Default constructor
115
- * - [EmplaceConstructible][]: Constructor selected by the given arguments
116
- * - [MoveAssignable][]: Move assignment operator
117
- * - [CopyAssignable][]: Copy assignment operator
115
+ * - [DefaultInsertable][]: Default constructor
116
+ * - [MoveInsertable][]: Move constructor
117
+ * - [CopyInsertable][]: Copy constructor
118
+ * - [DefaultConstructible][]: Default constructor
119
+ * - [EmplaceConstructible][]: Constructor selected by the given arguments
120
+ * - [MoveAssignable][]: Move assignment operator
121
+ * - [CopyAssignable][]: Copy assignment operator
118
122
  *
119
123
  * Furthermore, not `noexcept` methods throws whatever the allocator throws
120
124
  * if memory allocation fails. Such methods also throw `length_error` if the capacity
@@ -123,9 +127,7 @@ struct reserve_only_tag_t {};
123
127
  * **Remark**: If a method invalidates some iterators, it also invalidates references
124
128
  * and pointers to the elements pointed by the invalidated iterators.
125
129
  *
126
- * **Policies**:
127
- *
128
- * @ref devector_growth_policy models the `GrowthFactor` concept.
130
+ *! \tparam Options A type produced from \c boost::container::devector_options.
129
131
  *
130
132
  * [SequenceContainer]: http://en.cppreference.com/w/cpp/concept/SequenceContainer
131
133
  * [ReversibleContainer]: http://en.cppreference.com/w/cpp/concept/ReversibleContainer
@@ -145,32 +147,34 @@ class devector
145
147
  {
146
148
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
147
149
  typedef boost::container::allocator_traits
148
- <typename real_allocator<T, A>::type> allocator_traits_type;
149
- typedef typename allocator_traits_type::size_type alloc_size_type;
150
- typedef typename get_devector_opt<Options, alloc_size_type>::type options_type;
151
- typedef typename options_type::growth_factor_type growth_factor_type;
152
- typedef typename options_type::stored_size_type stored_size_type;
150
+ <typename real_allocator<T, A>::type> allocator_traits_type;
151
+ typedef typename allocator_traits_type::size_type alloc_size_type;
152
+ typedef typename get_devector_opt<Options, alloc_size_type>::type options_type;
153
+ typedef typename options_type::growth_factor_type growth_factor_type;
154
+ typedef typename options_type::stored_size_type stored_size_type;
155
+ static const std::size_t devector_min_free_fraction =
156
+ options_type::free_fraction;
153
157
 
154
158
  #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
155
159
 
156
160
  public:
157
161
  // Standard Interface Types:
158
- typedef T value_type;
162
+ typedef T value_type;
159
163
  typedef BOOST_CONTAINER_IMPDEF
160
- (typename real_allocator<T BOOST_MOVE_I A>::type) allocator_type;
161
- typedef allocator_type stored_allocator_type;
162
- typedef typename allocator_traits<allocator_type>::pointer pointer;
163
- typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
164
- typedef typename allocator_traits<allocator_type>::reference reference;
165
- typedef typename allocator_traits<allocator_type>::const_reference const_reference;
166
- typedef typename allocator_traits<allocator_type>::size_type size_type;
167
- typedef typename allocator_traits<allocator_type>::difference_type difference_type;
168
- typedef pointer iterator;
169
- typedef const_pointer const_iterator;
164
+ (typename real_allocator<T BOOST_MOVE_I A>::type) allocator_type;
165
+ typedef allocator_type stored_allocator_type;
166
+ typedef typename allocator_traits<allocator_type>::pointer pointer;
167
+ typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
168
+ typedef typename allocator_traits<allocator_type>::reference reference;
169
+ typedef typename allocator_traits<allocator_type>::const_reference const_reference;
170
+ typedef typename allocator_traits<allocator_type>::size_type size_type;
171
+ typedef typename allocator_traits<allocator_type>::difference_type difference_type;
172
+ typedef pointer iterator;
173
+ typedef const_pointer const_iterator;
170
174
  typedef BOOST_CONTAINER_IMPDEF
171
- (boost::container::reverse_iterator<iterator>) reverse_iterator;
175
+ (boost::container::reverse_iterator<iterator>) reverse_iterator;
172
176
  typedef BOOST_CONTAINER_IMPDEF
173
- (boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
177
+ (boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
174
178
 
175
179
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
176
180
  private:
@@ -182,6 +186,15 @@ class devector
182
186
  // Random access pseudo iterator always yielding to the same result
183
187
  typedef constant_iterator<T> cvalue_iterator;
184
188
 
189
+ static size_type to_internal_capacity(size_type desired_capacity)
190
+ {
191
+ const size_type rounder = devector_min_free_fraction - 2u;
192
+ const size_type divisor = devector_min_free_fraction - 1u;
193
+ size_type const nc = ((desired_capacity + rounder) / divisor) * devector_min_free_fraction;
194
+ BOOST_ASSERT(desired_capacity <= (nc - nc / devector_min_free_fraction));
195
+ return nc;
196
+ }
197
+
185
198
  #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
186
199
 
187
200
  // Standard Interface
@@ -216,63 +229,71 @@ class devector
216
229
  * **Effects**: Constructs an empty devector, using the specified allocator
217
230
  * and reserves `n` slots as if `reserve(n)` was called.
218
231
  *
219
- * **Postcondition**: `empty() && front_free_capacity() == 0
220
- * && back_free_capacity() >= n`.
232
+ * **Postcondition**: `empty() && capacity() >= n`.
221
233
  *
222
234
  * **Exceptions**: Strong exception guarantee.
223
235
  *
224
236
  * **Complexity**: Constant.
225
237
  */
226
238
  devector(size_type n, reserve_only_tag_t, const allocator_type& allocator = allocator_type())
227
- : m_(allocator, 0u, 0u, n)
239
+ : m_(reserve_only_tag_t(), allocator, to_internal_capacity(n))
228
240
  {}
229
241
 
230
242
  /**
231
243
  * **Effects**: Constructs an empty devector, using the specified allocator
232
- * and reserves `front_cap + back_cap` slots as if `reserve_front(front_cap)` and
244
+ * and reserves at least `front_free_cap + back_free_cap` slots as if `reserve_front(front_cap)` and
233
245
  * `reserve_back(back_cap)` was called.
234
246
  *
235
- * **Postcondition**: `empty() && front_free_capacity() == front_cap
236
- * && back_free_capacity() >= back_cap`.
247
+ * **Postcondition**: `empty() && front_free_capacity() >= front_free_cap
248
+ * && back_free_capacity() >= back_free_cap`.
237
249
  *
238
250
  * **Exceptions**: Strong exception guarantee.
239
251
  *
240
252
  * **Complexity**: Constant.
241
253
  */
242
- devector(size_type front_cap, size_type back_cap, reserve_only_tag_t, const allocator_type& allocator = allocator_type())
243
- : m_( allocator, front_cap, back_cap, front_cap + back_cap)
254
+ devector(size_type front_free_cap, size_type back_free_cap, reserve_only_tag_t, const allocator_type& allocator = allocator_type())
255
+ : m_(reserve_only_tag_t(), allocator, front_free_cap, back_free_cap)
244
256
  {}
245
257
 
246
258
  /**
247
259
  * [DefaultInsertable]: http://en.cppreference.com/w/cpp/concept/DefaultInsertable
248
260
  *
249
- * **Effects**: Constructs a devector with `n` default-inserted elements using the specified allocator.
261
+ * **Effects**: Constructs a devector with `n` value_initialized elements using the specified allocator.
250
262
  *
251
263
  * **Requires**: `T` shall be [DefaultInsertable] into `*this`.
252
264
  *
253
- * **Postcondition**: `size() == n && front_free_capacity() == 0`.
265
+ * **Postcondition**: `size() == n`.
254
266
  *
255
267
  * **Exceptions**: Strong exception guarantee.
256
268
  *
257
269
  * **Complexity**: Linear in `n`.
258
270
  */
259
271
  explicit devector(size_type n, const allocator_type& allocator = allocator_type())
260
- : m_(allocator, 0u, n, n)
272
+ : m_(reserve_uninitialized_t(), allocator, n)
261
273
  {
262
- // Cannot use construct_from_range/constant_iterator and copy_range,
263
- // because we are not allowed to default construct T
264
274
  allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
265
- detail::construction_guard<allocator_type> copy_guard(m_.buffer, get_allocator_ref());
266
-
267
- for (size_type i = 0; i < n; ++i)
268
- {
269
- this->alloc_construct(m_.buffer + i);
270
- copy_guard.extend();
271
- }
272
-
273
- copy_guard.release();
275
+ boost::container::uninitialized_value_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin());
274
276
  buffer_guard.release();
277
+ BOOST_ASSERT(invariants_ok());
278
+ }
275
279
 
280
+ /**
281
+ * **Effects**: Constructs a devector with `n` default-initialized elements using the specified allocator.
282
+ *
283
+ * **Requires**: `T` shall be [DefaultInsertable] into `*this`.
284
+ *
285
+ * **Postcondition**: `size() == n`.
286
+ *
287
+ * **Exceptions**: Strong exception guarantee.
288
+ *
289
+ * **Complexity**: Linear in `n`.
290
+ */
291
+ explicit devector(size_type n, default_init_t, const allocator_type& allocator = allocator_type())
292
+ : m_(reserve_uninitialized_t(), allocator, n)
293
+ {
294
+ allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
295
+ boost::container::uninitialized_default_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin());
296
+ buffer_guard.release();
276
297
  BOOST_ASSERT(invariants_ok());
277
298
  }
278
299
 
@@ -283,14 +304,14 @@ class devector
283
304
  *
284
305
  * **Requires**: `T` shall be [CopyInsertable] into `*this`.
285
306
  *
286
- * **Postcondition**: `size() == n && front_free_capacity() == 0`.
307
+ * **Postcondition**: `size() == n`.
287
308
  *
288
309
  * **Exceptions**: Strong exception guarantee.
289
310
  *
290
311
  * **Complexity**: Linear in `n`.
291
312
  */
292
313
  devector(size_type n, const T& value, const allocator_type& allocator = allocator_type())
293
- : m_(allocator, n ? allocate(n): pointer(), 0u, n, n)
314
+ : m_(reserve_uninitialized_t(), allocator, n)
294
315
  {
295
316
  construct_from_range(cvalue_iterator(value, n), cvalue_iterator());
296
317
  BOOST_ASSERT(invariants_ok());
@@ -322,18 +343,24 @@ class devector
322
343
  devector(InputIterator first, InputIterator last, const allocator_type& allocator = allocator_type()
323
344
  //Input iterators
324
345
  BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
325
- < void
326
- BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
327
- BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
328
- >::type * = 0)
346
+ < void
347
+ BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
348
+ BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
349
+ >::type * = 0)
329
350
  )
330
- : m_(allocator, pointer(), 0u, 0u, 0u)
351
+ : m_(allocator)
331
352
  {
332
- while (first != last) {
333
- this->emplace_back(*first++);
353
+ BOOST_TRY{
354
+ while (first != last) {
355
+ this->emplace_back(*first++);
356
+ }
357
+ BOOST_ASSERT(invariants_ok());
334
358
  }
335
-
336
- BOOST_ASSERT(invariants_ok());
359
+ BOOST_CATCH(...){
360
+ this->destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
361
+ this->deallocate_buffer();
362
+ }
363
+ BOOST_CATCH_END
337
364
  }
338
365
 
339
366
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -342,20 +369,13 @@ class devector
342
369
  devector(ForwardIterator first, ForwardIterator last, const allocator_type& allocator = allocator_type()
343
370
  //Other iterators
344
371
  BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
345
- < void
346
- BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
347
- BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
348
- >::type * = 0)
372
+ < void
373
+ BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
374
+ BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
375
+ >::type * = 0)
349
376
  )
350
- : m_(allocator)
377
+ : m_(reserve_uninitialized_t(), allocator, boost::container::iterator_udistance(first, last))
351
378
  {
352
- const size_type n = boost::container::iterator_udistance(first, last);
353
- m_.buffer = n ? allocate(n) : pointer();
354
- m_.front_idx = 0u;
355
- //this->allocate(n) will take care of overflows
356
- m_.set_back_idx(n);
357
- m_.set_capacity(n);
358
- //construct_from_range releases memory on failure
359
379
  this->construct_from_range(first, last);
360
380
  BOOST_ASSERT(invariants_ok());
361
381
  }
@@ -369,21 +389,15 @@ class devector
369
389
  *
370
390
  * **Requires**: `T` shall be [CopyInsertable] into `*this`.
371
391
  *
372
- * **Postcondition**: `this->size() == x.size() && front_free_capacity() == 0`.
392
+ * **Postcondition**: `this->size() == x.size()`.
373
393
  *
374
394
  * **Exceptions**: Strong exception guarantee.
375
395
  *
376
396
  * **Complexity**: Linear in the size of `x`.
377
397
  */
378
398
  devector(const devector& x)
379
- : m_( allocator_traits_type::select_on_container_copy_construction(x.get_allocator_ref()))
399
+ : m_(reserve_uninitialized_t(), allocator_traits_type::select_on_container_copy_construction(x.get_allocator_ref()), x.size())
380
400
  {
381
- const size_type n = x.size();
382
- m_.buffer = n ? allocate(n) : pointer();
383
- m_.front_idx = 0u;
384
- //this->allocate(n) will take care of overflows
385
- m_.set_back_idx(n);
386
- m_.set_capacity(n);
387
401
  this->construct_from_range(x.begin(), x.end());
388
402
  BOOST_ASSERT(invariants_ok());
389
403
  }
@@ -395,21 +409,15 @@ class devector
395
409
  *
396
410
  * **Requires**: `T` shall be [CopyInsertable] into `*this`.
397
411
  *
398
- * **Postcondition**: `this->size() == x.size() && front_free_capacity() == 0`.
412
+ * **Postcondition**: `*this == x`.
399
413
  *
400
414
  * **Exceptions**: Strong exception guarantee.
401
415
  *
402
416
  * **Complexity**: Linear in the size of `x`.
403
417
  */
404
418
  devector(const devector& x, const allocator_type& allocator)
405
- : m_(allocator, pointer(), 0u, 0u, 0u)
419
+ : m_(reserve_uninitialized_t(), allocator, x.size())
406
420
  {
407
- const size_type n = x.size();
408
- m_.buffer = n ? this->allocate(n) : pointer();
409
- m_.front_idx = 0u;
410
- //this->allocate(n) will take care of overflows
411
- m_.set_back_idx(n);
412
- m_.set_capacity(n);
413
421
  this->construct_from_range(x.begin(), x.end());
414
422
  BOOST_ASSERT(invariants_ok());
415
423
  }
@@ -419,21 +427,17 @@ class devector
419
427
  *
420
428
  * **Throws**: Nothing.
421
429
  *
422
- * **Postcondition**: `rhs` is left in an unspecified but valid state.
430
+ * **Postcondition**: *this has the same value `rhs` had before the operation.
431
+ * `rhs` is left in an unspecified but valid state.
423
432
  *
424
433
  * **Exceptions**: Strong exception guarantee if not `noexcept`.
425
434
  *
426
435
  * **Complexity**: Constant.
427
436
  */
428
437
  devector(BOOST_RV_REF(devector) rhs) BOOST_NOEXCEPT_OR_NOTHROW
429
- : m_(::boost::move(rhs.get_allocator_ref()), rhs.m_.buffer, rhs.m_.front_idx, rhs.m_.back_idx, rhs.capacity())
438
+ : m_(::boost::move(rhs.m_))
430
439
  {
431
- // buffer is already acquired, reset rhs
432
- rhs.m_.capacity = 0u;
433
- rhs.m_.buffer = pointer();
434
- rhs.m_.front_idx = 0;
435
- rhs.m_.back_idx = 0;
436
- BOOST_ASSERT( invariants_ok());
440
+ BOOST_ASSERT( invariants_ok());
437
441
  BOOST_ASSERT(rhs.invariants_ok());
438
442
  }
439
443
 
@@ -442,14 +446,15 @@ class devector
442
446
  *
443
447
  * **Throws**: If allocation or T's move constructor throws.
444
448
  *
445
- * **Postcondition**: `rhs` is left in an unspecified but valid state.
449
+ * **Postcondition**: *this has the same value `rhs` had before the operation.
450
+ * `rhs` is left in an unspecified but valid state.
446
451
  *
447
452
  * **Exceptions**: Strong exception guarantee if not `noexcept`.
448
453
  *
449
454
  * **Complexity**: Linear if allocator != rhs.get_allocator(), otherwise constant.
450
455
  */
451
456
  devector(BOOST_RV_REF(devector) rhs, const allocator_type& allocator)
452
- : m_(allocator, rhs.m_.buffer, rhs.m_.front_idx, rhs.m_.back_idx, rhs.capacity())
457
+ : m_(review_implementation_t(), allocator, rhs.m_.buffer, rhs.m_.front_idx, rhs.m_.back_idx, rhs.m_.capacity)
453
458
  {
454
459
  // TODO should move elems-by-elems if the two allocators differ
455
460
  // buffer is already acquired, reset rhs
@@ -457,42 +462,35 @@ class devector
457
462
  rhs.m_.buffer = pointer();
458
463
  rhs.m_.front_idx = 0;
459
464
  rhs.m_.back_idx = 0;
460
- BOOST_ASSERT( invariants_ok());
465
+ BOOST_ASSERT( invariants_ok());
461
466
  BOOST_ASSERT(rhs.invariants_ok());
462
467
  }
463
468
 
464
469
  #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
465
470
  /**
466
- * **Equivalent to**: `devector(il.begin(), il.end())` or `devector(il.begin(), il.end(), allocator)`.
471
+ * **Equivalent to**: `devector(il.begin(), il.end(), allocator)`.
467
472
  */
468
473
  devector(const std::initializer_list<T>& il, const allocator_type& allocator = allocator_type())
469
- : m_(allocator)
474
+ : m_(reserve_uninitialized_t(), allocator, il.size())
470
475
  {
471
- const size_type n = il.size();
472
- m_.buffer = n ? allocate(n) : pointer();
473
- m_.front_idx = 0u;
474
- //this->allocate(n) will take care of overflows
475
- m_.set_back_idx(n);
476
- m_.set_capacity(n);
477
- //construct_from_range releases memory on failure
478
476
  this->construct_from_range(il.begin(), il.end());
479
477
  BOOST_ASSERT(invariants_ok());
480
478
  }
481
479
  #endif
482
480
 
483
- /**
481
+ /**
484
482
  * **Effects**: Destroys the devector. All stored values are destroyed and
485
483
  * used memory, if any, deallocated.
486
484
  *
487
485
  * **Complexity**: Linear in the size of `*this`.
488
486
  */
489
- ~devector() BOOST_NOEXCEPT
490
- {
491
- destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
492
- deallocate_buffer();
493
- }
487
+ ~devector() BOOST_NOEXCEPT
488
+ {
489
+ destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
490
+ deallocate_buffer();
491
+ }
494
492
 
495
- /**
493
+ /**
496
494
  * **Effects**: Copies elements of `x` to `*this`. Previously
497
495
  * held elements get copy assigned to or destroyed.
498
496
  *
@@ -521,28 +519,28 @@ class devector
521
519
 
522
520
  BOOST_IF_CONSTEXPR(allocator_traits_type::propagate_on_container_copy_assignment::value)
523
521
  {
524
- allocator_type &this_alloc = this->get_allocator_ref();
525
- const allocator_type &other_alloc = x.get_allocator_ref();
526
- if (this_alloc != other_alloc)
527
- {
528
- // new allocator cannot free existing storage
529
- this->clear();
530
- this->deallocate_buffer();
531
- m_.capacity = 0u;
532
- m_.buffer = pointer();
533
- }
522
+ allocator_type &this_alloc = this->get_allocator_ref();
523
+ const allocator_type &other_alloc = x.get_allocator_ref();
524
+ if (this_alloc != other_alloc)
525
+ {
526
+ // new allocator cannot free existing storage
527
+ this->clear();
528
+ this->deallocate_buffer();
529
+ m_.capacity = 0u;
530
+ m_.buffer = pointer();
531
+ }
534
532
 
535
- this_alloc = other_alloc;
533
+ this_alloc = other_alloc;
536
534
  }
537
535
 
538
536
  size_type n = x.size();
539
- if (capacity() >= n)
537
+ if (m_.capacity >= n)
540
538
  {
541
- this->overwrite_buffer(x.begin(), x.end());
539
+ this->overwrite_buffer(x.begin(), x.end());
542
540
  }
543
541
  else
544
542
  {
545
- this->allocate_and_copy_range(x.begin(), x.end());
543
+ this->allocate_and_copy_range(x.begin(), x.end());
546
544
  }
547
545
 
548
546
  BOOST_ASSERT(invariants_ok());
@@ -565,12 +563,12 @@ class devector
565
563
  * **Exceptions**: Basic exception guarantee if not `noexcept`.
566
564
  *
567
565
  * **Complexity**: Constant if allocator_traits_type::
568
- * propagate_on_container_move_assignment is true or
569
- * this->get>allocator() == x.get_allocator(). Linear otherwise.
566
+ * propagate_on_container_move_assignment is true or
567
+ * this->get>allocator() == x.get_allocator(). Linear otherwise.
570
568
  */
571
569
  devector& operator=(BOOST_RV_REF(devector) x)
572
570
  BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
573
- || allocator_traits_type::is_always_equal::value)
571
+ || allocator_traits_type::is_always_equal::value)
574
572
  {
575
573
  BOOST_CONSTEXPR_OR_CONST bool copy_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
576
574
 
@@ -607,7 +605,7 @@ class devector
607
605
  get_allocator_ref() = boost::move(x.get_allocator_ref());
608
606
  }
609
607
 
610
- if (capacity() >= x.size())
608
+ if (m_.capacity >= x.size())
611
609
  {
612
610
  overwrite_buffer(xbegin, xend);
613
611
  }
@@ -642,9 +640,9 @@ class devector
642
640
  * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
643
641
  * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
644
642
  */
645
- devector& operator=(std::initializer_list<T> il)
643
+ BOOST_CONTAINER_FORCEINLINE devector& operator=(std::initializer_list<T> il)
646
644
  {
647
- assign(il.begin(), il.end());
645
+ this->assign(il.begin(), il.end());
648
646
  return *this;
649
647
  }
650
648
  #endif
@@ -678,10 +676,10 @@ class devector
678
676
  void assign(InputIterator first, InputIterator last
679
677
  //Input iterators
680
678
  BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
681
- < void
682
- BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
683
- BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
684
- >::type * = 0)
679
+ < void
680
+ BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
681
+ BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
682
+ >::type * = 0)
685
683
  )
686
684
  {
687
685
  first = overwrite_buffer_impl(first, last, dtl::false_());
@@ -697,15 +695,15 @@ class devector
697
695
  void assign(ForwardIterator first, ForwardIterator last
698
696
  //Other iterators
699
697
  BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
700
- < void
701
- BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
702
- BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
703
- >::type * = 0)
698
+ < void
699
+ BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
700
+ BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
701
+ >::type * = 0)
704
702
  )
705
703
  {
706
704
  const size_type n = boost::container::iterator_udistance(first, last);
707
705
 
708
- if (capacity() >= n)
706
+ if (m_.capacity >= n)
709
707
  {
710
708
  overwrite_buffer(first, last);
711
709
  }
@@ -719,293 +717,290 @@ class devector
719
717
 
720
718
  #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
721
719
 
722
- /**
723
- * **Effects**: Replaces elements of `*this` with `n` copies of `u`.
724
- * Previously held elements get copy assigned to or destroyed.
725
- *
726
- * **Requires**: `T` shall be [CopyInsertable] into `*this` and
727
- * [CopyAssignable].
728
- *
729
- * **Precondition**: `u` is not a reference into `*this`.
730
- *
731
- * **Postcondition**: `size() == n` and the elements of
732
- * `*this` are copies of `u`.
733
- *
734
- * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable
735
- * from `u` and `NothrowConstructible`, Basic exception guarantee otherwise.
736
- *
737
- * **Complexity**: Linear in `n` and the size of `*this`.
738
- *
739
- * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
740
- * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
741
- */
742
- void assign(size_type n, const T& u)
743
- {
744
- cvalue_iterator first(u, n);
745
- cvalue_iterator last;
720
+ /**
721
+ * **Effects**: Replaces elements of `*this` with `n` copies of `u`.
722
+ * Previously held elements get copy assigned to or destroyed.
723
+ *
724
+ * **Requires**: `T` shall be [CopyInsertable] into `*this` and
725
+ * [CopyAssignable].
726
+ *
727
+ * **Precondition**: `u` is not a reference into `*this`.
728
+ *
729
+ * **Postcondition**: `size() == n` and the elements of
730
+ * `*this` are copies of `u`.
731
+ *
732
+ * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable
733
+ * from `u` and `NothrowConstructible`, Basic exception guarantee otherwise.
734
+ *
735
+ * **Complexity**: Linear in `n` and the size of `*this`.
736
+ *
737
+ * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
738
+ * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
739
+ */
740
+ BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& u)
741
+ {
742
+ cvalue_iterator first(u, n);
743
+ cvalue_iterator last;
744
+ this->assign(first, last);
745
+ }
746
+
747
+ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
748
+ /** **Equivalent to**: `assign(il.begin(), il.end())`. */
749
+ BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<T> il)
750
+ {
751
+ this->assign(il.begin(), il.end());
752
+ }
753
+ #endif
746
754
 
747
- assign(first, last);
748
- }
755
+ /**
756
+ * **Returns**: A copy of the allocator associated with the container.
757
+ *
758
+ * **Complexity**: Constant.
759
+ */
760
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
761
+ allocator_type get_allocator() const BOOST_NOEXCEPT
762
+ {
763
+ return static_cast<const allocator_type&>(m_);
764
+ }
749
765
 
750
- #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
751
- /** **Equivalent to**: `assign(il.begin(), il.end())`. */
752
- void assign(std::initializer_list<T> il)
766
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
767
+ const allocator_type &get_stored_allocator() const BOOST_NOEXCEPT
753
768
  {
754
- assign(il.begin(), il.end());
769
+ return static_cast<const allocator_type&>(m_);
755
770
  }
756
- #endif
757
771
 
758
- /**
759
- * **Returns**: A copy of the allocator associated with the container.
760
- *
761
- * **Complexity**: Constant.
762
- */
763
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
764
- allocator_type get_allocator() const BOOST_NOEXCEPT
765
- {
766
- return static_cast<const allocator_type&>(m_);
767
- }
768
-
769
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
770
- const allocator_type &get_stored_allocator() const BOOST_NOEXCEPT
771
- {
772
- return static_cast<const allocator_type&>(m_);
773
- }
774
-
775
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
776
- allocator_type &get_stored_allocator() BOOST_NOEXCEPT
777
- {
778
- return static_cast<allocator_type&>(m_);
779
- }
780
-
781
- // iterators
782
-
783
- /**
784
- * **Returns**: A iterator pointing to the first element in the devector,
785
- * or the past the end iterator if the devector is empty.
786
- *
787
- * **Complexity**: Constant.
788
- */
789
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
790
- iterator begin() BOOST_NOEXCEPT
791
- {
792
- return m_.buffer + m_.front_idx;
793
- }
772
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
773
+ allocator_type &get_stored_allocator() BOOST_NOEXCEPT
774
+ {
775
+ return static_cast<allocator_type&>(m_);
776
+ }
794
777
 
795
- /**
796
- * **Returns**: A constant iterator pointing to the first element in the devector,
797
- * or the past the end iterator if the devector is empty.
798
- *
799
- * **Complexity**: Constant.
800
- */
801
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
802
- const_iterator begin() const BOOST_NOEXCEPT
803
- {
804
- return m_.buffer + m_.front_idx;
805
- }
778
+ // iterators
806
779
 
807
- /**
808
- * **Returns**: An iterator pointing past the last element of the container.
809
- *
810
- * **Complexity**: Constant.
811
- */
812
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
813
- iterator end() BOOST_NOEXCEPT
814
- {
815
- return m_.buffer + m_.back_idx;
816
- }
780
+ /**
781
+ * **Returns**: A iterator pointing to the first element in the devector,
782
+ * or the past the end iterator if the devector is empty.
783
+ *
784
+ * **Complexity**: Constant.
785
+ */
786
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
787
+ iterator begin() BOOST_NOEXCEPT
788
+ {
789
+ return m_.buffer + m_.front_idx;
790
+ }
817
791
 
818
- /**
819
- * **Returns**: A constant iterator pointing past the last element of the container.
820
- *
821
- * **Complexity**: Constant.
822
- */
823
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
824
- const_iterator end() const BOOST_NOEXCEPT
825
- {
826
- return m_.buffer + m_.back_idx;
827
- }
792
+ /**
793
+ * **Returns**: A constant iterator pointing to the first element in the devector,
794
+ * or the past the end iterator if the devector is empty.
795
+ *
796
+ * **Complexity**: Constant.
797
+ */
798
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
799
+ const_iterator begin() const BOOST_NOEXCEPT
800
+ {
801
+ return m_.buffer + m_.front_idx;
802
+ }
828
803
 
829
- /**
830
- * **Returns**: A reverse iterator pointing to the first element in the reversed devector,
831
- * or the reverse past the end iterator if the devector is empty.
832
- *
833
- * **Complexity**: Constant.
834
- */
835
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
836
- reverse_iterator rbegin() BOOST_NOEXCEPT
837
- {
838
- return reverse_iterator(m_.buffer + m_.back_idx);
839
- }
804
+ /**
805
+ * **Returns**: An iterator pointing past the last element of the container.
806
+ *
807
+ * **Complexity**: Constant.
808
+ */
809
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
810
+ iterator end() BOOST_NOEXCEPT
811
+ {
812
+ return m_.buffer + m_.back_idx;
813
+ }
840
814
 
841
- /**
842
- * **Returns**: A constant reverse iterator
843
- * pointing to the first element in the reversed devector,
844
- * or the reverse past the end iterator if the devector is empty.
845
- *
846
- * **Complexity**: Constant.
847
- */
848
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
849
- const_reverse_iterator rbegin() const BOOST_NOEXCEPT
850
- {
851
- return const_reverse_iterator(m_.buffer + m_.back_idx);
852
- }
815
+ /**
816
+ * **Returns**: A constant iterator pointing past the last element of the container.
817
+ *
818
+ * **Complexity**: Constant.
819
+ */
820
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
821
+ const_iterator end() const BOOST_NOEXCEPT
822
+ {
823
+ return m_.buffer + m_.back_idx;
824
+ }
853
825
 
854
- /**
855
- * **Returns**: A reverse iterator pointing past the last element in the
856
- * reversed container, or to the beginning of the reversed container if it's empty.
857
- *
858
- * **Complexity**: Constant.
859
- */
860
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
861
- reverse_iterator rend() BOOST_NOEXCEPT
862
- {
863
- return reverse_iterator(m_.buffer + m_.front_idx);
864
- }
826
+ /**
827
+ * **Returns**: A reverse iterator pointing to the first element in the reversed devector,
828
+ * or the reverse past the end iterator if the devector is empty.
829
+ *
830
+ * **Complexity**: Constant.
831
+ */
832
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
833
+ reverse_iterator rbegin() BOOST_NOEXCEPT
834
+ {
835
+ return reverse_iterator(m_.buffer + m_.back_idx);
836
+ }
865
837
 
866
- /**
867
- * **Returns**: A constant reverse iterator pointing past the last element in the
868
- * reversed container, or to the beginning of the reversed container if it's empty.
869
- *
870
- * **Complexity**: Constant.
871
- */
872
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
873
- const_reverse_iterator rend() const BOOST_NOEXCEPT
874
- {
875
- return const_reverse_iterator(m_.buffer + m_.front_idx);
876
- }
838
+ /**
839
+ * **Returns**: A constant reverse iterator
840
+ * pointing to the first element in the reversed devector,
841
+ * or the reverse past the end iterator if the devector is empty.
842
+ *
843
+ * **Complexity**: Constant.
844
+ */
845
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
846
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT
847
+ {
848
+ return const_reverse_iterator(m_.buffer + m_.back_idx);
849
+ }
877
850
 
878
- /**
879
- * **Returns**: A constant iterator pointing to the first element in the devector,
880
- * or the past the end iterator if the devector is empty.
881
- *
882
- * **Complexity**: Constant.
883
- */
884
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
885
- const_iterator cbegin() const BOOST_NOEXCEPT
886
- {
887
- return m_.buffer + m_.front_idx;
888
- }
851
+ /**
852
+ * **Returns**: A reverse iterator pointing past the last element in the
853
+ * reversed container, or to the beginning of the reversed container if it's empty.
854
+ *
855
+ * **Complexity**: Constant.
856
+ */
857
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
858
+ reverse_iterator rend() BOOST_NOEXCEPT
859
+ {
860
+ return reverse_iterator(m_.buffer + m_.front_idx);
861
+ }
889
862
 
890
- /**
891
- * **Returns**: A constant iterator pointing past the last element of the container.
892
- *
893
- * **Complexity**: Constant.
894
- */
895
- const_iterator cend() const BOOST_NOEXCEPT
896
- {
897
- return m_.buffer + m_.back_idx;
898
- }
863
+ /**
864
+ * **Returns**: A constant reverse iterator pointing past the last element in the
865
+ * reversed container, or to the beginning of the reversed container if it's empty.
866
+ *
867
+ * **Complexity**: Constant.
868
+ */
869
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
870
+ const_reverse_iterator rend() const BOOST_NOEXCEPT
871
+ {
872
+ return const_reverse_iterator(m_.buffer + m_.front_idx);
873
+ }
899
874
 
900
- /**
901
- * **Returns**: A constant reverse iterator
902
- * pointing to the first element in the reversed devector,
903
- * or the reverse past the end iterator if the devector is empty.
904
- *
905
- * **Complexity**: Constant.
906
- */
907
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
908
- const_reverse_iterator crbegin() const BOOST_NOEXCEPT
909
- {
910
- return const_reverse_iterator(m_.buffer + m_.back_idx);
911
- }
875
+ /**
876
+ * **Returns**: A constant iterator pointing to the first element in the devector,
877
+ * or the past the end iterator if the devector is empty.
878
+ *
879
+ * **Complexity**: Constant.
880
+ */
881
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
882
+ const_iterator cbegin() const BOOST_NOEXCEPT
883
+ {
884
+ return m_.buffer + m_.front_idx;
885
+ }
912
886
 
913
- /**
914
- * **Returns**: A constant reverse iterator pointing past the last element in the
915
- * reversed container, or to the beginning of the reversed container if it's empty.
916
- *
917
- * **Complexity**: Constant.
918
- */
919
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
920
- const_reverse_iterator crend() const BOOST_NOEXCEPT
921
- {
922
- return const_reverse_iterator(m_.buffer + m_.front_idx);
923
- }
887
+ /**
888
+ * **Returns**: A constant iterator pointing past the last element of the container.
889
+ *
890
+ * **Complexity**: Constant.
891
+ */
892
+ const_iterator cend() const BOOST_NOEXCEPT
893
+ {
894
+ return m_.buffer + m_.back_idx;
895
+ }
924
896
 
925
- // capacity
897
+ /**
898
+ * **Returns**: A constant reverse iterator
899
+ * pointing to the first element in the reversed devector,
900
+ * or the reverse past the end iterator if the devector is empty.
901
+ *
902
+ * **Complexity**: Constant.
903
+ */
904
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
905
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT
906
+ {
907
+ return const_reverse_iterator(m_.buffer + m_.back_idx);
908
+ }
926
909
 
927
- /**
928
- * **Returns**: True, if `size() == 0`, false otherwise.
929
- *
930
- * **Complexity**: Constant.
931
- */
932
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
933
- bool empty() const BOOST_NOEXCEPT
934
- {
935
- return m_.front_idx == m_.back_idx;
936
- }
910
+ /**
911
+ * **Returns**: A constant reverse iterator pointing past the last element in the
912
+ * reversed container, or to the beginning of the reversed container if it's empty.
913
+ *
914
+ * **Complexity**: Constant.
915
+ */
916
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
917
+ const_reverse_iterator crend() const BOOST_NOEXCEPT
918
+ {
919
+ return const_reverse_iterator(m_.buffer + m_.front_idx);
920
+ }
937
921
 
938
- /**
939
- * **Returns**: The number of elements the devector contains.
940
- *
941
- * **Complexity**: Constant.
942
- */
943
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
944
- size_type size() const BOOST_NOEXCEPT
945
- {
946
- return size_type(m_.back_idx - m_.front_idx);
947
- }
922
+ // capacity
948
923
 
949
- /**
950
- * **Returns**: The maximum number of elements the devector could possibly hold.
951
- *
952
- * **Complexity**: Constant.
953
- */
954
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
955
- size_type max_size() const BOOST_NOEXCEPT
956
- {
957
- size_type alloc_max = allocator_traits_type::max_size(get_allocator_ref());
958
- size_type size_type_max = (size_type)-1;
959
- return (alloc_max <= size_type_max) ? size_type(alloc_max) : size_type_max;
960
- }
924
+ /**
925
+ * **Returns**: True, if `size() == 0`, false otherwise.
926
+ *
927
+ * **Complexity**: Constant.
928
+ */
929
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
930
+ bool empty() const BOOST_NOEXCEPT
931
+ {
932
+ return m_.front_idx == m_.back_idx;
933
+ }
961
934
 
962
- /**
963
- * **Returns**: The total number of elements that the devector can hold without requiring reallocation.
964
- *
965
- * **Complexity**: Constant.
966
- */
967
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
968
- size_type capacity() const BOOST_NOEXCEPT
969
- {
970
- return m_.capacity;
971
- }
935
+ /**
936
+ * **Returns**: The number of elements the devector contains.
937
+ *
938
+ * **Complexity**: Constant.
939
+ */
940
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
941
+ size_type size() const BOOST_NOEXCEPT
942
+ {
943
+ return size_type(m_.back_idx - m_.front_idx);
944
+ }
972
945
 
973
- /**
974
- * **Returns**: The total number of elements that can be pushed to the front of the
975
- * devector without requiring reallocation.
976
- *
977
- * **Complexity**: Constant.
978
- */
979
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
980
- size_type front_free_capacity() const BOOST_NOEXCEPT
981
- {
982
- return m_.front_idx;
983
- }
946
+ /**
947
+ * **Returns**: The maximum number of elements the devector could possibly hold.
948
+ *
949
+ * **Complexity**: Constant.
950
+ */
951
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
952
+ size_type max_size() const BOOST_NOEXCEPT
953
+ {
954
+ size_type alloc_max = allocator_traits_type::max_size(get_allocator_ref());
955
+ size_type size_type_max = (size_type)-1;
956
+ return (alloc_max <= size_type_max) ? size_type(alloc_max) : size_type_max;
957
+ }
984
958
 
985
- /**
986
- * **Returns**: The total number of elements that can be pushed to the back of the
987
- * devector without requiring reallocation.
988
- *
959
+ /**
960
+ * **Returns**: The *minimum* number of elements that can be inserted into devector using
961
+ * position-based insertions without requiring a reallocation. Note that, unlike in
962
+ * typical sequence containers like `vector`, `capacity()`, `capacity()` can be smaller than `size()`.
963
+ * This can happen if a user inserts elements in a particular way (usually inserting at
964
+ * front up to front_free_capacity() and at back up to back_free_capacity()).
965
+ *
989
966
  * **Complexity**: Constant.
990
967
  */
991
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
992
- size_type back_free_capacity() const BOOST_NOEXCEPT
993
- {
994
- return size_type(m_.capacity - m_.back_idx);
995
- }
968
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
969
+ size_type capacity() const BOOST_NOEXCEPT
970
+ {
971
+ size_type const cap_reserve = m_.capacity/devector_min_free_fraction;
972
+ return m_.capacity > cap_reserve ? (m_.capacity - cap_reserve) : 0u;
973
+ }
996
974
 
997
- /** **Equivalent to**: `resize_back(sz)` */
998
- void resize(size_type sz) { resize_back(sz); }
975
+ /**
976
+ * **Returns**: The total number of elements that can be pushed to the front of the
977
+ * devector without requiring reallocation.
978
+ *
979
+ * **Complexity**: Constant.
980
+ */
981
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
982
+ size_type front_free_capacity() const BOOST_NOEXCEPT
983
+ {
984
+ return m_.front_idx;
985
+ }
999
986
 
1000
- /** **Equivalent to**: `resize_back(sz, c)` */
1001
- void resize(size_type sz, const T& c) { resize_back(sz, c); }
987
+ /**
988
+ * **Returns**: The total number of elements that can be pushed to the back of the
989
+ * devector without requiring reallocation.
990
+ *
991
+ * **Complexity**: Constant.
992
+ */
993
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
994
+ size_type back_free_capacity() const BOOST_NOEXCEPT
995
+ {
996
+ return size_type(m_.capacity - m_.back_idx);
997
+ }
1002
998
 
1003
- /**
999
+ /**
1004
1000
  * **Effects**: If `sz` is greater than the size of `*this`,
1005
- * additional value-initialized elements are inserted
1006
- * to the front. Invalidates iterators if reallocation is needed.
1007
- * If `sz` is smaller than than the size of `*this`,
1008
- * elements are popped from the front.
1001
+ * additional value-initialized elements are inserted. Invalidates iterators
1002
+ * if reallocation is needed. If `sz` is smaller than than the size of `*this`,
1003
+ * elements are erased from the extremes.
1009
1004
  *
1010
1005
  * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1011
1006
  *
@@ -1018,20 +1013,27 @@ class devector
1018
1013
  * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1019
1014
  * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1020
1015
  */
1021
- void resize_front(size_type sz)
1022
- {
1023
- resize_front_impl(sz);
1024
- BOOST_ASSERT(invariants_ok());
1025
- }
1016
+ BOOST_CONTAINER_FORCEINLINE void resize(size_type sz)
1017
+ {
1018
+ this->resize_back(sz);
1019
+ }
1020
+
1021
+ /**
1022
+ * **Effects**: Same as resize(sz) but creates default-initialized
1023
+ * value-initialized.
1024
+ */
1025
+ BOOST_CONTAINER_FORCEINLINE void resize(size_type sz, default_init_t)
1026
+ {
1027
+ this->resize_back(sz, default_init);
1028
+ }
1026
1029
 
1027
- /**
1030
+ /**
1028
1031
  * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1029
1032
  *
1030
1033
  * **Effects**: If `sz` is greater than the size of `*this`,
1031
- * copies of `c` are inserted to the front.
1032
- * Invalidates iterators if reallocation is needed.
1034
+ * copies of `c` are inserted at extremes.
1033
1035
  * If `sz` is smaller than than the size of `*this`,
1034
- * elements are popped from the front.
1036
+ * elements are popped from the extremes.
1035
1037
  *
1036
1038
  * **Postcondition**: `sz == size()`.
1037
1039
  *
@@ -1041,230 +1043,276 @@ class devector
1041
1043
  *
1042
1044
  * **Complexity**: Linear in the size of `*this` and `sz`.
1043
1045
  */
1044
- void resize_front(size_type sz, const T& c)
1045
- {
1046
- resize_front_impl(sz, c);
1047
- BOOST_ASSERT(invariants_ok());
1048
- }
1046
+ BOOST_CONTAINER_FORCEINLINE void resize(size_type sz, const T& c)
1047
+ {
1048
+ this->resize_back(sz, c);
1049
+ }
1049
1050
 
1050
- /**
1051
- * **Effects**: If `sz` is greater than the size of `*this`,
1052
- * additional value-initialized elements are inserted
1053
- * to the back. Invalidates iterators if reallocation is needed.
1054
- * If `sz` is smaller than than the size of `*this`,
1055
- * elements are popped from the back.
1056
- *
1057
- * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1058
- *
1059
- * **Postcondition**: `sz == size()`.
1060
- *
1061
- * **Exceptions**: Strong exception guarantee.
1062
- *
1063
- * **Complexity**: Linear in the size of `*this` and `sz`.
1064
- *
1065
- * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1066
- * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1067
- */
1068
- void resize_back(size_type sz)
1069
- {
1070
- resize_back_impl(sz);
1071
- BOOST_ASSERT(invariants_ok());
1072
- }
1051
+ /**
1052
+ * **Effects**: If `sz` is greater than the size of `*this`,
1053
+ * additional value-initialized elements are inserted
1054
+ * to the front. Invalidates iterators if reallocation is needed.
1055
+ * If `sz` is smaller than than the size of `*this`,
1056
+ * elements are popped from the front.
1057
+ *
1058
+ * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1059
+ *
1060
+ * **Postcondition**: `sz == size()`.
1061
+ *
1062
+ * **Exceptions**: Strong exception guarantee.
1063
+ *
1064
+ * **Complexity**: Linear in the size of `*this` and `sz`.
1065
+ *
1066
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1067
+ * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1068
+ */
1069
+ BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz)
1070
+ {
1071
+ resize_front_impl(sz);
1072
+ BOOST_ASSERT(invariants_ok());
1073
+ }
1073
1074
 
1074
- /**
1075
- * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1076
- *
1077
- * **Effects**: If `sz` is greater than the size of `*this`,
1078
- * copies of `c` are inserted to the back.
1079
- * If `sz` is smaller than than the size of `*this`,
1080
- * elements are popped from the back.
1081
- *
1082
- * **Postcondition**: `sz == size()`.
1083
- *
1084
- * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1085
- *
1086
- * **Exceptions**: Strong exception guarantee.
1087
- *
1088
- * **Complexity**: Linear in the size of `*this` and `sz`.
1089
- */
1090
- void resize_back(size_type sz, const T& c)
1091
- {
1092
- resize_back_impl(sz, c);
1093
- BOOST_ASSERT(invariants_ok());
1094
- }
1095
-
1096
- // unsafe uninitialized resize methods
1097
-
1098
- /**
1099
- * **Unsafe method**, use with care.
1100
- *
1101
- * **Effects**: Changes the size of the devector without properly
1102
- * initializing the extra or destroying the superfluous elements.
1103
- * If `n < size()`, elements are removed from the front without
1104
- * getting destroyed; if `n > size()`, uninitialized elements are added
1105
- * before the first element at the front.
1106
- * Invalidates iterators if reallocation is needed.
1107
- *
1108
- * **Postcondition**: `size() == n`.
1109
- *
1110
- * **Exceptions**: Strong exception guarantee.
1111
- *
1112
- * **Complexity**: Linear in `size()` if `capacity() < n`, constant otherwise.
1113
- *
1114
- * **Remarks**: The devector does not keep track of initialization of the elements:
1115
- * Elements without a trivial destructor must be manually destroyed before shrinking,
1116
- * elements without a trivial constructor must be initialized after growing.
1117
- */
1118
- /*
1119
- void unsafe_uninitialized_resize_front(size_type n)
1120
- {
1121
- if (n > size())
1122
- {
1123
- unsafe_uninitialized_grow_front(n);
1124
- }
1125
- else
1126
- {
1127
- unsafe_uninitialized_shrink_front(n);
1128
- }
1129
- }
1130
- */
1131
- /**
1132
- * **Unsafe method**, use with care.
1133
- *
1134
- * **Effects**: Changes the size of the devector without properly
1135
- * initializing the extra or destroying the superfluous elements.
1136
- * If `n < size()`, elements are removed from the back without
1137
- * getting destroyed; if `n > size()`, uninitialized elements are added
1138
- * after the last element at the back.
1139
- * Invalidates iterators if reallocation is needed.
1140
- *
1141
- * **Postcondition**: `size() == n`.
1142
- *
1143
- * **Exceptions**: Strong exception guarantee.
1144
- *
1145
- * **Complexity**: Linear in `size()` if `capacity() < n`, constant otherwise.
1146
- *
1147
- * **Remarks**: The devector does not keep track of initialization of the elements:
1148
- * Elements without a trivial destructor must be manually destroyed before shrinking,
1149
- * elements without a trivial constructor must be initialized after growing.
1150
- */
1151
- /*
1152
- void unsafe_uninitialized_resize_back(size_type n)
1153
- {
1154
- if (n > size())
1155
- {
1156
- unsafe_uninitialized_grow_back(n);
1157
- }
1158
- else
1159
- {
1160
- unsafe_uninitialized_shrink_back(n);
1161
- }
1162
- }
1163
- */
1164
- // reserve promise:
1165
- // after reserve_[front,back](n), n - size() push_[front,back] will not allocate
1075
+ /**
1076
+ * **Effects**: If `sz` is greater than the size of `*this`,
1077
+ * additional value-initialized elements are inserted
1078
+ * to the front. Invalidates iterators if reallocation is needed.
1079
+ * If `sz` is smaller than than the size of `*this`,
1080
+ * elements are popped from the front.
1081
+ *
1082
+ * **Requires**: T shall be [MoveInsertable] into *this and default_initializable.
1083
+ *
1084
+ * **Postcondition**: `sz == size()`.
1085
+ *
1086
+ * **Exceptions**: Strong exception guarantee.
1087
+ *
1088
+ * **Complexity**: Linear in the size of `*this` and `sz`.
1089
+ *
1090
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1091
+ */
1092
+ BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz, default_init_t)
1093
+ {
1094
+ resize_front_impl(sz, default_init);
1095
+ BOOST_ASSERT(invariants_ok());
1096
+ }
1166
1097
 
1167
- /** **Equivalent to**: `reserve_back(new_capacity)` */
1168
- void reserve(size_type new_capacity) { reserve_back(new_capacity); }
1098
+ /**
1099
+ * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1100
+ *
1101
+ * **Effects**: If `sz` is greater than the size of `*this`,
1102
+ * copies of `c` are inserted to the front.
1103
+ * Invalidates iterators if reallocation is needed.
1104
+ * If `sz` is smaller than than the size of `*this`,
1105
+ * elements are popped from the front.
1106
+ *
1107
+ * **Postcondition**: `sz == size()`.
1108
+ *
1109
+ * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1110
+ *
1111
+ * **Exceptions**: Strong exception guarantee.
1112
+ *
1113
+ * **Complexity**: Linear in the size of `*this` and `sz`.
1114
+ */
1115
+ BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz, const T& c)
1116
+ {
1117
+ resize_front_impl(sz, c);
1118
+ BOOST_ASSERT(invariants_ok());
1119
+ }
1169
1120
 
1170
- /**
1171
- * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1172
- *
1173
- * **Effects**: Ensures that `n` elements can be pushed to the front
1174
- * without requiring reallocation, where `n` is `new_capacity - size()`,
1175
- * if `n` is positive. Otherwise, there are no effects.
1176
- * Invalidates iterators if reallocation is needed.
1177
- *
1178
- * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1179
- *
1180
- * **Complexity**: Linear in the size of *this.
1181
- *
1182
- * **Exceptions**: Strong exception guarantee.
1183
- *
1184
- * **Throws**: `length_error` if `new_capacity > max_size()`.
1185
- */
1186
- void reserve_front(size_type new_capacity)
1187
- {
1188
- if (front_capacity() >= new_capacity) { return; }
1121
+ /**
1122
+ * **Effects**: If `sz` is greater than the size of `*this`,
1123
+ * additional value-initialized elements are inserted
1124
+ * to the back. Invalidates iterators if reallocation is needed.
1125
+ * If `sz` is smaller than than the size of `*this`,
1126
+ * elements are popped from the back.
1127
+ *
1128
+ * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1129
+ *
1130
+ * **Postcondition**: `sz == size()`.
1131
+ *
1132
+ * **Exceptions**: Strong exception guarantee.
1133
+ *
1134
+ * **Complexity**: Linear in the size of `*this` and `sz`.
1135
+ *
1136
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1137
+ * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1138
+ */
1139
+ BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz)
1140
+ {
1141
+ resize_back_impl(sz);
1142
+ BOOST_ASSERT(invariants_ok());
1143
+ }
1189
1144
 
1190
- reallocate_at(new_capacity + back_free_capacity(), new_capacity - size());
1145
+ /**
1146
+ * **Effects**: If `sz` is greater than the size of `*this`,
1147
+ * additional value-initialized elements are inserted
1148
+ * to the back. Invalidates iterators if reallocation is needed.
1149
+ * If `sz` is smaller than than the size of `*this`,
1150
+ * elements are popped from the back.
1151
+ *
1152
+ * **Requires**: T shall be [MoveInsertable] into *this and default initializable.
1153
+ *
1154
+ * **Postcondition**: `sz == size()`.
1155
+ *
1156
+ * **Exceptions**: Strong exception guarantee.
1157
+ *
1158
+ * **Complexity**: Linear in the size of `*this` and `sz`.
1159
+ *
1160
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1161
+ */
1162
+ BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz, default_init_t)
1163
+ {
1164
+ resize_back_impl(sz, default_init);
1165
+ BOOST_ASSERT(invariants_ok());
1166
+ }
1191
1167
 
1192
- BOOST_ASSERT(invariants_ok());
1193
- }
1168
+ /**
1169
+ * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1170
+ *
1171
+ * **Effects**: If `sz` is greater than the size of `*this`,
1172
+ * copies of `c` are inserted to the back.
1173
+ * If `sz` is smaller than than the size of `*this`,
1174
+ * elements are popped from the back.
1175
+ *
1176
+ * **Postcondition**: `sz == size()`.
1177
+ *
1178
+ * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1179
+ *
1180
+ * **Exceptions**: Strong exception guarantee.
1181
+ *
1182
+ * **Complexity**: Linear in the size of `*this` and `sz`.
1183
+ */
1184
+ BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz, const T& c)
1185
+ {
1186
+ resize_back_impl(sz, c);
1187
+ BOOST_ASSERT(invariants_ok());
1188
+ }
1194
1189
 
1195
- /**
1196
- * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1197
- *
1198
- * **Effects**: Ensures that `n` elements can be pushed to the back
1199
- * without requiring reallocation, where `n` is `new_capacity - size()`,
1200
- * if `n` is positive. Otherwise, there are no effects.
1201
- * Invalidates iterators if reallocation is needed.
1202
- *
1203
- * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1204
- *
1205
- * **Complexity**: Linear in the size of *this.
1206
- *
1207
- * **Exceptions**: Strong exception guarantee.
1208
- *
1209
- * **Throws**: length_error if `new_capacity > max_size()`.
1210
- */
1211
- void reserve_back(size_type new_capacity)
1212
- {
1213
- if (back_capacity() >= new_capacity) { return; }
1190
+ /**
1191
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1192
+ *
1193
+ * **Effects**: Ensures that at least `n` elements can be inserted
1194
+ * without requiring reallocation, where `n` is `new_capacity - size()`,
1195
+ * if `n` is positive. Otherwise, there are no effects.
1196
+ * Invalidates iterators if reallocation is needed.
1197
+ *
1198
+ * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1199
+ *
1200
+ * **Complexity**: Linear in the size of *this.
1201
+ *
1202
+ * **Exceptions**: Strong exception guarantee.
1203
+ *
1204
+ * **Throws**: length_error if `new_capacity > max_size()`.
1205
+ */
1206
+ BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_capacity)
1207
+ {
1208
+ if (this->capacity() < new_capacity) {
1209
+ const size_type rounder = devector_min_free_fraction - 2u;
1210
+ const size_type divisor = devector_min_free_fraction - 1u;
1211
+ size_type const nc = ((new_capacity + rounder)/divisor)*devector_min_free_fraction;
1212
+ BOOST_ASSERT(new_capacity <= (nc - nc / devector_min_free_fraction));
1213
+ size_type const sz = this->size();
1214
+ reallocate_at(nc, (nc-sz)/2u);
1215
+ }
1216
+ BOOST_ASSERT(invariants_ok());
1217
+ }
1218
+
1219
+ /**
1220
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1221
+ *
1222
+ * **Effects**: Ensures that `n` elements can be pushed to the front
1223
+ * without requiring reallocation, where `n` is `new_capacity - size()`,
1224
+ * if `n` is positive. Otherwise, there are no effects.
1225
+ * Invalidates iterators if reallocation is needed.
1226
+ *
1227
+ * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1228
+ *
1229
+ * **Complexity**: Linear in the size of *this.
1230
+ *
1231
+ * **Exceptions**: Strong exception guarantee.
1232
+ *
1233
+ * **Throws**: `length_error` if `new_capacity > max_size()`.
1234
+ */
1235
+ BOOST_CONTAINER_FORCEINLINE void reserve_front(size_type new_capacity)
1236
+ {
1237
+ if (front_capacity() >= new_capacity) { return; }
1238
+
1239
+ reallocate_at(new_capacity + back_free_capacity(), new_capacity - size());
1214
1240
 
1215
- reallocate_at(new_capacity + front_free_capacity(), m_.front_idx);
1241
+ BOOST_ASSERT(invariants_ok());
1242
+ }
1216
1243
 
1217
- BOOST_ASSERT(invariants_ok());
1218
- }
1244
+ /**
1245
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1246
+ *
1247
+ * **Effects**: Ensures that `n` elements can be pushed to the back
1248
+ * without requiring reallocation, where `n` is `new_capacity - size()`,
1249
+ * if `n` is positive. Otherwise, there are no effects.
1250
+ * Invalidates iterators if reallocation is needed.
1251
+ *
1252
+ * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1253
+ *
1254
+ * **Complexity**: Linear in the size of *this.
1255
+ *
1256
+ * **Exceptions**: Strong exception guarantee.
1257
+ *
1258
+ * **Throws**: length_error if `new_capacity > max_size()`.
1259
+ */
1260
+ BOOST_CONTAINER_FORCEINLINE void reserve_back(size_type new_capacity)
1261
+ {
1262
+ if (back_capacity() >= new_capacity) { return; }
1263
+
1264
+ reallocate_at(new_capacity + front_free_capacity(), m_.front_idx);
1219
1265
 
1266
+ BOOST_ASSERT(invariants_ok());
1267
+ }
1220
1268
 
1221
- /**
1222
- * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1223
- *
1224
- * **Effects**: Reduces `capacity()` to `size()`. Invalidates iterators.
1225
- *
1226
- * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1227
- *
1228
- * **Exceptions**: Strong exception guarantee.
1229
- *
1230
- * **Complexity**: Linear in the size of *this.
1231
- */
1232
- void shrink_to_fit()
1233
- {
1269
+
1270
+ /**
1271
+ * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1272
+ *
1273
+ * **Effects**: Reduces `capacity()` to `size()`. Invalidates iterators.
1274
+ *
1275
+ * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1276
+ *
1277
+ * **Exceptions**: Strong exception guarantee.
1278
+ *
1279
+ * **Complexity**: Linear in the size of *this.
1280
+ */
1281
+ BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
1282
+ {
1234
1283
  if(this->front_capacity() || this->back_capacity())
1235
- this->reallocate_at(size(), 0);
1236
- }
1284
+ this->reallocate_at(size(), 0);
1285
+ }
1237
1286
 
1238
- // element access:
1287
+ // element access:
1239
1288
 
1240
- /**
1241
- * **Returns**: A reference to the `n`th element in the devector.
1242
- *
1243
- * **Precondition**: `n < size()`.
1244
- *
1245
- * **Complexity**: Constant.
1246
- */
1247
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1289
+ /**
1290
+ * **Returns**: A reference to the `n`th element in the devector.
1291
+ *
1292
+ * **Precondition**: `n < size()`.
1293
+ *
1294
+ * **Complexity**: Constant.
1295
+ */
1296
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1248
1297
  reference operator[](size_type n) BOOST_NOEXCEPT
1249
- {
1250
- BOOST_ASSERT(n < size());
1251
- return *(begin() + n);
1252
- }
1298
+ {
1299
+ BOOST_ASSERT(n < size());
1300
+ return m_.buffer[m_.front_idx + n];
1301
+ }
1253
1302
 
1254
- /**
1255
- * **Returns**: A constant reference to the `n`th element in the devector.
1256
- *
1257
- * **Precondition**: `n < size()`.
1258
- *
1259
- * **Complexity**: Constant.
1260
- */
1261
- BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1303
+ /**
1304
+ * **Returns**: A constant reference to the `n`th element in the devector.
1305
+ *
1306
+ * **Precondition**: `n < size()`.
1307
+ *
1308
+ * **Complexity**: Constant.
1309
+ */
1310
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1262
1311
  const_reference operator[](size_type n) const BOOST_NOEXCEPT
1263
- {
1264
- BOOST_ASSERT(n < size());
1265
-
1266
- return *(begin() + n);
1267
- }
1312
+ {
1313
+ BOOST_ASSERT(n < size());
1314
+ return m_.buffer[m_.front_idx + n];
1315
+ }
1268
1316
 
1269
1317
  /**
1270
1318
  * **Returns**: A reference to the `n`th element in the devector.
@@ -1277,7 +1325,7 @@ class devector
1277
1325
  reference at(size_type n)
1278
1326
  {
1279
1327
  if (size() <= n)
1280
- throw_out_of_range("devector::at out of range");
1328
+ throw_out_of_range("devector::at out of range");
1281
1329
  return (*this)[n];
1282
1330
  }
1283
1331
 
@@ -1292,7 +1340,7 @@ class devector
1292
1340
  const_reference at(size_type n) const
1293
1341
  {
1294
1342
  if (size() <= n)
1295
- throw_out_of_range("devector::at out of range");
1343
+ throw_out_of_range("devector::at out of range");
1296
1344
  return (*this)[n];
1297
1345
  }
1298
1346
 
@@ -1308,7 +1356,7 @@ class devector
1308
1356
  {
1309
1357
  BOOST_ASSERT(!empty());
1310
1358
 
1311
- return *(m_.buffer + m_.front_idx);
1359
+ return m_.buffer[m_.front_idx];
1312
1360
  }
1313
1361
 
1314
1362
  /**
@@ -1323,7 +1371,7 @@ class devector
1323
1371
  {
1324
1372
  BOOST_ASSERT(!empty());
1325
1373
 
1326
- return *(m_.buffer + m_.front_idx);
1374
+ return m_.buffer[m_.front_idx];
1327
1375
  }
1328
1376
 
1329
1377
  /**
@@ -1338,7 +1386,7 @@ class devector
1338
1386
  {
1339
1387
  BOOST_ASSERT(!empty());
1340
1388
 
1341
- return *(m_.buffer + m_.back_idx -1);
1389
+ return m_.buffer[m_.back_idx - 1u];
1342
1390
  }
1343
1391
 
1344
1392
  /**
@@ -1353,7 +1401,7 @@ class devector
1353
1401
  {
1354
1402
  BOOST_ASSERT(!empty());
1355
1403
 
1356
- return *(m_.buffer + m_.back_idx -1);
1404
+ return m_.buffer[m_.back_idx - 1u];
1357
1405
  }
1358
1406
 
1359
1407
  /**
@@ -1402,38 +1450,41 @@ class devector
1402
1450
  */
1403
1451
  #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1404
1452
  template <class... Args>
1405
- void emplace_front(Args&&... args)
1453
+ reference emplace_front(Args&&... args)
1406
1454
  {
1407
- if (front_free_capacity()) // fast path
1455
+ if (BOOST_LIKELY(front_free_capacity() != 0)) // fast path
1408
1456
  {
1409
- this->alloc_construct(m_.buffer + m_.front_idx - 1, boost::forward<Args>(args)...);
1457
+ pointer const p = m_.buffer + (m_.front_idx - 1u);
1458
+ this->alloc_construct(p, boost::forward<Args>(args)...);
1410
1459
  --m_.front_idx;
1460
+ BOOST_ASSERT(invariants_ok());
1461
+ return *p;
1411
1462
  }
1412
1463
  else
1413
1464
  {
1414
- this->emplace_reallocating_slow_path(true, 0, boost::forward<Args>(args)...);
1465
+ typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1466
+ return *this->insert_range_slow_path(this->begin(), 1, proxy_t(::boost::forward<Args>(args)...));
1415
1467
  }
1416
-
1417
- BOOST_ASSERT(invariants_ok());
1418
1468
  }
1419
1469
 
1420
1470
  #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1421
1471
 
1422
1472
  #define BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT(N) \
1423
1473
  BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1424
- BOOST_CONTAINER_FORCEINLINE void emplace_front(BOOST_MOVE_UREF##N)\
1474
+ BOOST_CONTAINER_FORCEINLINE reference emplace_front(BOOST_MOVE_UREF##N)\
1425
1475
  {\
1426
1476
  if (front_free_capacity())\
1427
1477
  {\
1428
- this->alloc_construct(m_.buffer + m_.front_idx - 1 BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1478
+ pointer const p = m_.buffer + (m_.front_idx - 1u);\
1479
+ this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1429
1480
  --m_.front_idx;\
1481
+ return *p;\
1430
1482
  }\
1431
1483
  else\
1432
1484
  {\
1433
- this->emplace_reallocating_slow_path(true, 0 BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1485
+ typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1486
+ return *this->insert_range_slow_path(this->begin(), 1, proxy_t(BOOST_MOVE_FWD##N));\
1434
1487
  }\
1435
- \
1436
- BOOST_ASSERT(invariants_ok());\
1437
1488
  }\
1438
1489
  //
1439
1490
  BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT)
@@ -1489,8 +1540,8 @@ class devector
1489
1540
  */
1490
1541
  void pop_front() BOOST_NOEXCEPT
1491
1542
  {
1492
- BOOST_ASSERT(! empty());
1493
- allocator_traits_type::destroy(get_allocator_ref(), m_.buffer + m_.front_idx);
1543
+ BOOST_ASSERT(!empty());
1544
+ allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(m_.buffer + m_.front_idx));
1494
1545
  ++m_.front_idx;
1495
1546
  BOOST_ASSERT(invariants_ok());
1496
1547
  }
@@ -1515,38 +1566,43 @@ class devector
1515
1566
  */
1516
1567
  #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1517
1568
  template <class... Args>
1518
- BOOST_CONTAINER_FORCEINLINE void emplace_back(Args&&... args)
1569
+ BOOST_CONTAINER_FORCEINLINE reference emplace_back(Args&&... args)
1519
1570
  {
1520
- if (this->back_free_capacity()){
1521
- this->alloc_construct(m_.buffer + m_.back_idx, boost::forward<Args>(args)...);
1571
+ if (BOOST_LIKELY(this->back_free_capacity() != 0)){
1572
+ pointer const p = m_.buffer + m_.back_idx;
1573
+ this->alloc_construct(p, boost::forward<Args>(args)...);
1522
1574
  ++m_.back_idx;
1575
+ BOOST_ASSERT(invariants_ok());
1576
+ return *p;
1523
1577
  }
1524
1578
  else {
1525
- this->emplace_reallocating_slow_path(false, size(), boost::forward<Args>(args)...);
1579
+ typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1580
+ return *this->insert_range_slow_path(this->end(), 1, proxy_t(::boost::forward<Args>(args)...));
1526
1581
  }
1527
- BOOST_ASSERT(invariants_ok());
1528
1582
  }
1529
1583
 
1530
1584
  #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1531
1585
 
1532
1586
  #define BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK(N) \
1533
1587
  BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1534
- BOOST_CONTAINER_FORCEINLINE void emplace_back(BOOST_MOVE_UREF##N)\
1588
+ BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\
1535
1589
  {\
1536
1590
  if (this->back_free_capacity()){\
1537
- this->alloc_construct(m_.buffer + m_.back_idx BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1591
+ pointer const p = m_.buffer + m_.back_idx;\
1592
+ this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1538
1593
  ++m_.back_idx;\
1594
+ return *p;\
1539
1595
  }\
1540
1596
  else {\
1541
- this->emplace_reallocating_slow_path(false, size() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1597
+ typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1598
+ return *this->insert_range_slow_path(this->end(), 1, proxy_t(BOOST_MOVE_FWD##N));\
1542
1599
  }\
1543
- BOOST_ASSERT(invariants_ok());\
1544
1600
  }\
1545
1601
  //
1546
1602
  BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK)
1547
1603
  #undef BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK
1548
1604
 
1549
- #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1605
+ #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1550
1606
 
1551
1607
 
1552
1608
  #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1599,7 +1655,7 @@ class devector
1599
1655
  {
1600
1656
  BOOST_ASSERT(! empty());
1601
1657
  --m_.back_idx;
1602
- allocator_traits_type::destroy(get_allocator_ref(), m_.buffer + m_.back_idx);
1658
+ allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(m_.buffer + m_.back_idx));
1603
1659
  BOOST_ASSERT(invariants_ok());
1604
1660
  }
1605
1661
 
@@ -1628,24 +1684,56 @@ class devector
1628
1684
  {
1629
1685
  BOOST_ASSERT(position >= begin());
1630
1686
  BOOST_ASSERT(position <= end());
1631
-
1632
- if (position == end() && back_free_capacity()) // fast path
1633
- {
1634
- this->alloc_construct(m_.buffer + m_.back_idx, boost::forward<Args>(args)...);
1635
- ++m_.back_idx;
1636
- return end() - 1;
1687
+ typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1688
+ bool prefer_move_back;
1689
+ if (position == end()){
1690
+ if(back_free_capacity()) // fast path
1691
+ {
1692
+ pointer const p = m_.buffer + m_.back_idx;
1693
+ this->alloc_construct(p, boost::forward<Args>(args)...);
1694
+ ++m_.back_idx;
1695
+ return iterator(p);
1696
+ }
1697
+ prefer_move_back = true;
1637
1698
  }
1638
- else if (position == begin() && front_free_capacity()) // secondary fast path
1639
- {
1640
- this->alloc_construct(m_.buffer + (m_.front_idx - 1), boost::forward<Args>(args)...);
1641
- --m_.front_idx;
1642
- return begin();
1699
+ else if (position == begin()){
1700
+ if(front_free_capacity()) // secondary fast path
1701
+ {
1702
+ pointer const p = m_.buffer + (m_.front_idx - 1);
1703
+ this->alloc_construct(p, boost::forward<Args>(args)...);
1704
+ --m_.front_idx;
1705
+ return iterator(p);
1706
+ }
1707
+ prefer_move_back = false;
1643
1708
  }
1644
- else
1645
- {
1646
- size_type new_elem_index = size_type(position - begin());
1647
- return this->emplace_slow_path(new_elem_index, boost::forward<Args>(args)...);
1709
+ else{
1710
+ iterator nonconst_pos = unconst_iterator(position);
1711
+ prefer_move_back = should_move_back(position);
1712
+
1713
+ if(prefer_move_back){
1714
+ if(back_free_capacity()){
1715
+ boost::container::expand_forward_and_insert_nonempty_middle_alloc
1716
+ ( get_allocator_ref()
1717
+ , boost::movelib::to_raw_pointer(nonconst_pos)
1718
+ , this->priv_raw_end()
1719
+ , 1, proxy_t(::boost::forward<Args>(args)...));
1720
+ ++m_.back_idx;
1721
+ return nonconst_pos;
1722
+ }
1723
+ }
1724
+ else{
1725
+ if (front_free_capacity()){
1726
+ boost::container::expand_backward_and_insert_nonempty_middle_alloc
1727
+ (get_allocator_ref()
1728
+ , this->priv_raw_begin()
1729
+ , boost::movelib::to_raw_pointer(nonconst_pos)
1730
+ , 1, proxy_t(::boost::forward<Args>(args)...));
1731
+ --m_.front_idx;
1732
+ return --nonconst_pos;
1733
+ }
1734
+ }
1648
1735
  }
1736
+ return this->insert_range_slow_path(position, 1, proxy_t(::boost::forward<Args>(args)...));
1649
1737
  }
1650
1738
 
1651
1739
  #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1656,27 +1744,62 @@ class devector
1656
1744
  {\
1657
1745
  BOOST_ASSERT(position >= begin());\
1658
1746
  BOOST_ASSERT(position <= end());\
1659
- \
1660
- if (position == end() && back_free_capacity()){\
1661
- this->alloc_construct(m_.buffer + m_.back_idx BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1662
- ++m_.back_idx;\
1663
- return end() - 1;\
1747
+ typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1748
+ bool prefer_move_back;\
1749
+ if (position == end()){\
1750
+ if(back_free_capacity())\
1751
+ {\
1752
+ pointer const p = m_.buffer + m_.back_idx;\
1753
+ this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1754
+ ++m_.back_idx;\
1755
+ return iterator(p);\
1756
+ }\
1757
+ prefer_move_back = true;\
1664
1758
  }\
1665
- else if (position == begin() && front_free_capacity()){\
1666
- this->alloc_construct(m_.buffer + m_.front_idx - 1 BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1667
- --m_.front_idx;\
1668
- return begin();\
1759
+ else if (position == begin()){\
1760
+ if(front_free_capacity())\
1761
+ {\
1762
+ pointer const p = m_.buffer + (m_.front_idx - 1);\
1763
+ this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1764
+ --m_.front_idx;\
1765
+ return iterator(p);\
1766
+ }\
1767
+ prefer_move_back = false;\
1669
1768
  }\
1670
1769
  else{\
1671
- size_type new_elem_index = size_type(position - begin());\
1672
- return this->emplace_slow_path(new_elem_index BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1770
+ iterator nonconst_pos = unconst_iterator(position);\
1771
+ prefer_move_back = should_move_back(position);\
1772
+ \
1773
+ if(prefer_move_back){\
1774
+ if(back_free_capacity()){\
1775
+ boost::container::expand_forward_and_insert_nonempty_middle_alloc\
1776
+ ( get_allocator_ref()\
1777
+ , boost::movelib::to_raw_pointer(nonconst_pos)\
1778
+ , this->priv_raw_end()\
1779
+ , 1, proxy_t(BOOST_MOVE_FWD##N));\
1780
+ ++m_.back_idx;\
1781
+ return nonconst_pos;\
1782
+ }\
1783
+ }\
1784
+ else{\
1785
+ if (front_free_capacity()){\
1786
+ boost::container::expand_backward_and_insert_nonempty_middle_alloc\
1787
+ (get_allocator_ref()\
1788
+ , this->priv_raw_begin()\
1789
+ , boost::movelib::to_raw_pointer(nonconst_pos)\
1790
+ , 1, proxy_t(BOOST_MOVE_FWD##N));\
1791
+ --m_.front_idx;\
1792
+ return --nonconst_pos;\
1793
+ }\
1794
+ }\
1673
1795
  }\
1796
+ return this->insert_range_slow_path(position, 1, proxy_t(BOOST_MOVE_FWD##N));\
1674
1797
  }\
1675
1798
  //
1676
1799
  BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE)
1677
1800
  #undef BOOST_CONTAINER_DEVECTOR_EMPLACE
1678
1801
 
1679
- #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1802
+ #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1680
1803
 
1681
1804
 
1682
1805
  #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1736,16 +1859,16 @@ class devector
1736
1859
  * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1737
1860
  * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
1738
1861
  */
1739
- iterator insert(const_iterator position, size_type n, const T& x)
1862
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, size_type n, const T& x)
1740
1863
  {
1741
1864
  cvalue_iterator first(x, n);
1742
1865
  cvalue_iterator last = first + n;
1743
- return insert_range(position, first, last);
1866
+ return this->insert_range(position, first, last);
1744
1867
  }
1745
1868
 
1746
1869
  /**
1747
1870
  * **Effects**: Copy constructs elements before the element pointed by position
1748
- * using each element in the rage pointed by `first` and `last` as constructor arguments.
1871
+ * using each element in the range pointed by `first` and `last` as constructor arguments.
1749
1872
  * Invalidates iterators if reallocation is needed.
1750
1873
  *
1751
1874
  * **Requires**: `T` shall be [EmplaceConstructible] into `*this` from `*first`. If the specified iterator
@@ -1759,7 +1882,7 @@ class devector
1759
1882
  * **Complexity**: Linear in the size of `*this` and `N` (where `N` is the distance between `first` and `last`).
1760
1883
  * Makes only `N` calls to the constructor of `T` and no reallocations if iterators `first` and `last`
1761
1884
  * are of forward, bidirectional, or random access categories. It makes 2N calls to the copy constructor of `T`
1762
- * and allocates memory twice at most if they are just input iterators.
1885
+ * and `O(log(N)) reallocations if they are just input iterators.
1763
1886
  *
1764
1887
  * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
1765
1888
  * and `NothrowAssignable`, Basic exception guarantee otherwise.
@@ -1775,10 +1898,10 @@ class devector
1775
1898
  iterator insert(const_iterator position, InputIterator first, InputIterator last
1776
1899
  //Input iterators
1777
1900
  BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
1778
- < void
1779
- BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
1780
- BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
1781
- >::type * = 0)
1901
+ < void
1902
+ BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
1903
+ BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
1904
+ >::type * = 0)
1782
1905
  )
1783
1906
  {
1784
1907
  if (position == end())
@@ -1809,13 +1932,13 @@ class devector
1809
1932
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1810
1933
 
1811
1934
  template <class ForwardIterator>
1812
- iterator insert(const_iterator position, ForwardIterator first, ForwardIterator last
1935
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, ForwardIterator first, ForwardIterator last
1813
1936
  //Other iterators
1814
1937
  BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
1815
- < void
1816
- BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
1817
- BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
1818
- >::type * = 0)
1938
+ < void
1939
+ BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
1940
+ BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
1941
+ >::type * = 0)
1819
1942
  )
1820
1943
  {
1821
1944
  return insert_range(position, first, last);
@@ -1825,9 +1948,9 @@ class devector
1825
1948
 
1826
1949
  #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1827
1950
  /** **Equivalent to**: `insert(position, il.begin(), il.end())` */
1828
- iterator insert(const_iterator position, std::initializer_list<T> il)
1951
+ BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, std::initializer_list<T> il)
1829
1952
  {
1830
- return insert_range(position, il.begin(), il.end());
1953
+ return this->insert(position, il.begin(), il.end());
1831
1954
  }
1832
1955
  #endif
1833
1956
 
@@ -1875,8 +1998,8 @@ class devector
1875
1998
  */
1876
1999
  iterator erase(const_iterator first, const_iterator last)
1877
2000
  {
1878
- iterator nc_first = begin() + (first - begin());
1879
- iterator nc_last = begin() + (last - begin());
2001
+ iterator nc_first = unconst_iterator(first);
2002
+ iterator nc_last = unconst_iterator(last);
1880
2003
  return erase(nc_first, nc_last);
1881
2004
  }
1882
2005
 
@@ -1900,38 +2023,38 @@ class devector
1900
2023
  */
1901
2024
  iterator erase(iterator first, iterator last)
1902
2025
  {
1903
- size_type front_distance = size_type(last - begin());
2026
+ size_type front_distance = pos_to_index(last);
1904
2027
  size_type back_distance = size_type(end() - first);
1905
2028
  size_type n = boost::container::iterator_udistance(first, last);
1906
2029
 
1907
2030
  if (front_distance < back_distance)
1908
2031
  {
1909
- // move n to the right
1910
- boost::container::move_backward(begin(), first, last);
2032
+ // move n to the right
2033
+ boost::container::move_backward(begin(), first, last);
1911
2034
 
1912
- for (iterator i = begin(); i != begin() + n; ++i)
1913
- {
1914
- allocator_traits_type::destroy(get_allocator_ref(), i);
1915
- }
1916
- //n is always less than max stored_size_type
1917
- m_.set_front_idx(m_.front_idx + n);
2035
+ for (iterator i = begin(); i != begin() + n; ++i)
2036
+ {
2037
+ allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i));
2038
+ }
2039
+ //n is always less than max stored_size_type
2040
+ m_.set_front_idx(m_.front_idx + n);
1918
2041
 
1919
- BOOST_ASSERT(invariants_ok());
1920
- return last;
2042
+ BOOST_ASSERT(invariants_ok());
2043
+ return last;
1921
2044
  }
1922
2045
  else {
1923
- // move n to the left
1924
- boost::container::move(last, end(), first);
2046
+ // move n to the left
2047
+ boost::container::move(last, end(), first);
1925
2048
 
1926
- for (iterator i = end() - n; i != end(); ++i)
1927
- {
1928
- allocator_traits_type::destroy(get_allocator_ref(), i);
1929
- }
1930
- //n is always less than max stored_size_type
1931
- m_.set_back_idx(m_.back_idx - n);
2049
+ for (iterator i = end() - n; i != end(); ++i)
2050
+ {
2051
+ allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i));
2052
+ }
2053
+ //n is always less than max stored_size_type
2054
+ m_.set_back_idx(m_.back_idx - n);
1932
2055
 
1933
- BOOST_ASSERT(invariants_ok());
1934
- return first;
2056
+ BOOST_ASSERT(invariants_ok());
2057
+ return first;
1935
2058
  }
1936
2059
  }
1937
2060
 
@@ -1951,7 +2074,7 @@ class devector
1951
2074
  */
1952
2075
  void swap(devector& b)
1953
2076
  BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
1954
- || allocator_traits_type::is_always_equal::value)
2077
+ || allocator_traits_type::is_always_equal::value)
1955
2078
  {
1956
2079
  BOOST_CONSTEXPR_OR_CONST bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
1957
2080
  BOOST_ASSERT(propagate_alloc || get_allocator_ref() == b.get_allocator_ref()); // else it's undefined behavior
@@ -1965,7 +2088,7 @@ class devector
1965
2088
  //And now swap the allocator
1966
2089
  dtl::swap_alloc(this->get_allocator_ref(), b.get_allocator_ref(), dtl::bool_<propagate_alloc>());
1967
2090
 
1968
- BOOST_ASSERT( invariants_ok());
2091
+ BOOST_ASSERT( invariants_ok());
1969
2092
  BOOST_ASSERT(b.invariants_ok());
1970
2093
  }
1971
2094
 
@@ -1989,41 +2112,69 @@ class devector
1989
2112
 
1990
2113
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1991
2114
  friend bool operator==(const devector& x, const devector& y)
1992
- { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
2115
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
1993
2116
 
1994
2117
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1995
2118
  friend bool operator!=(const devector& x, const devector& y)
1996
- { return !(x == y); }
2119
+ { return !(x == y); }
1997
2120
 
1998
2121
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1999
2122
  friend bool operator< (const devector& x, const devector& y)
2000
- { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2123
+ { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2001
2124
 
2002
2125
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2003
2126
  friend bool operator>(const devector& x, const devector& y)
2004
- { return y < x; }
2127
+ { return y < x; }
2005
2128
 
2006
2129
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2007
2130
  friend bool operator<=(const devector& x, const devector& y)
2008
- { return !(y < x); }
2131
+ { return !(y < x); }
2009
2132
 
2010
2133
  BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2011
2134
  friend bool operator>=(const devector& x, const devector& y)
2012
- { return !(x < y); }
2135
+ { return !(x < y); }
2013
2136
 
2014
2137
  BOOST_CONTAINER_FORCEINLINE friend void swap(devector& x, devector& y)
2015
2138
  BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
2016
- || allocator_traits_type::is_always_equal::value)
2017
- { x.swap(y); }
2139
+ || allocator_traits_type::is_always_equal::value)
2140
+ { x.swap(y); }
2018
2141
 
2019
2142
  private:
2143
+
2144
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2145
+ size_type pos_to_index(const_iterator i) const
2146
+ {
2147
+ return static_cast<size_type>(i - cbegin());
2148
+ }
2149
+
2150
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2151
+ bool should_move_back(const_iterator i) const
2152
+ {
2153
+ return static_cast<size_type>(this->pos_to_index(i)) >= this->size()/2u;
2154
+ }
2155
+
2156
+ BOOST_CONTAINER_FORCEINLINE static iterator unconst_iterator(const_iterator i)
2157
+ {
2158
+ return boost::intrusive::pointer_traits<pointer>::const_cast_from(i);
2159
+ }
2160
+
2161
+ BOOST_CONTAINER_FORCEINLINE size_type front_capacity() const
2162
+ {
2163
+ return m_.back_idx;
2164
+ }
2165
+
2166
+ BOOST_CONTAINER_FORCEINLINE size_type back_capacity() const
2167
+ {
2168
+ return size_type(m_.capacity - m_.front_idx);
2169
+ }
2170
+
2020
2171
  #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2021
2172
 
2022
- BOOST_CONTAINER_FORCEINLINE T* raw_begin() BOOST_NOEXCEPT
2023
- { return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx; }
2173
+ BOOST_CONTAINER_FORCEINLINE T* priv_raw_begin() BOOST_NOEXCEPT
2174
+ { return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx; }
2024
2175
 
2025
- BOOST_CONTAINER_FORCEINLINE T* raw_end() BOOST_NOEXCEPT
2026
- { return boost::movelib::to_raw_pointer(m_.buffer) + m_.back_idx; }
2176
+ BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() BOOST_NOEXCEPT
2177
+ { return boost::movelib::to_raw_pointer(m_.buffer) + m_.back_idx; }
2027
2178
 
2028
2179
 
2029
2180
  template <class U>
@@ -2069,7 +2220,7 @@ class devector
2069
2220
  {
2070
2221
  for (; begin != end; ++begin)
2071
2222
  {
2072
- allocator_traits_type::destroy(get_allocator_ref(), begin);
2223
+ allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(begin));
2073
2224
  }
2074
2225
  }
2075
2226
 
@@ -2086,9 +2237,9 @@ class devector
2086
2237
  BOOST_CONTAINER_FORCEINLINE void alloc_construct(pointer dst, Args&&... args)
2087
2238
  {
2088
2239
  allocator_traits_type::construct(
2089
- get_allocator_ref(),
2090
- dst,
2091
- boost::forward<Args>(args)...
2240
+ get_allocator_ref(),
2241
+ boost::movelib::to_raw_pointer(dst),
2242
+ boost::forward<Args>(args)...
2092
2243
  );
2093
2244
  }
2094
2245
 
@@ -2116,7 +2267,7 @@ class devector
2116
2267
  BOOST_CONTAINER_FORCEINLINE void alloc_construct(pointer dst BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2117
2268
  {\
2118
2269
  allocator_traits_type::construct(\
2119
- get_allocator_ref(), dst BOOST_MOVE_I##N BOOST_MOVE_FWD##N );\
2270
+ get_allocator_ref(), boost::movelib::to_raw_pointer(dst) BOOST_MOVE_I##N BOOST_MOVE_FWD##N );\
2120
2271
  }\
2121
2272
  \
2122
2273
  BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
@@ -2131,25 +2282,15 @@ class devector
2131
2282
  void guarded_construct_n(pointer buffer, size_type n, detail::construction_guard<allocator_type>& ctr_guard BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2132
2283
  {\
2133
2284
  for (size_type i = 0; i < n; ++i) {\
2134
- this->alloc_construct(buffer + i BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2135
- ctr_guard.extend();\
2285
+ this->alloc_construct(buffer + i BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2286
+ ctr_guard.extend();\
2136
2287
  }\
2137
2288
  }
2138
2289
  //
2139
2290
  BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT)
2140
2291
  #undef BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT
2141
2292
 
2142
- #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2143
-
2144
- BOOST_CONTAINER_FORCEINLINE size_type front_capacity() const
2145
- {
2146
- return m_.back_idx;
2147
- }
2148
-
2149
- BOOST_CONTAINER_FORCEINLINE size_type back_capacity() const
2150
- {
2151
- return size_type(m_.capacity - m_.front_idx);
2152
- }
2293
+ #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2153
2294
 
2154
2295
  size_type calculate_new_capacity(size_type requested_capacity)
2155
2296
  {
@@ -2158,7 +2299,7 @@ class devector
2158
2299
  const size_type remaining_additional_cap = max - size_type(m_.capacity);
2159
2300
  const size_type min_additional_cap = requested_capacity - size_type(m_.capacity);
2160
2301
  if ( remaining_additional_cap < min_additional_cap )
2161
- boost::container::throw_length_error("devector: get_next_capacity, max size exceeded");
2302
+ boost::container::throw_length_error("devector: get_next_capacity, max size exceeded");
2162
2303
 
2163
2304
  return growth_factor_type()( size_type(m_.capacity), min_additional_cap, max);
2164
2305
  }
@@ -2180,21 +2321,6 @@ class devector
2180
2321
  deallocate_buffer();
2181
2322
  }
2182
2323
 
2183
- void opt_move_or_copy(pointer begin, pointer end, pointer dst)
2184
- {
2185
- typedef typename dtl::if_c
2186
- < boost::move_detail::is_nothrow_copy_constructible<T>::value || boost::is_nothrow_move_constructible<T>::value
2187
- , detail::null_construction_guard
2188
- , detail::construction_guard<allocator_type>
2189
- >::type guard_t;
2190
-
2191
- guard_t guard(dst, get_allocator_ref());
2192
-
2193
- opt_move_or_copy(begin, end, dst, guard);
2194
-
2195
- guard.release();
2196
- }
2197
-
2198
2324
  template <typename Guard>
2199
2325
  void opt_move_or_copy(pointer begin, pointer end, pointer dst, Guard& guard)
2200
2326
  {
@@ -2203,50 +2329,52 @@ class devector
2203
2329
  guard.extend();
2204
2330
  }
2205
2331
 
2206
- template <typename Iterator>
2207
- void opt_copy(Iterator begin, Iterator end, pointer dst)
2208
- {
2209
- typedef typename dtl::if_c
2210
- < boost::move_detail::is_nothrow_copy_constructible<T>::value
2211
- , detail::null_construction_guard
2212
- , detail::construction_guard<allocator_type>
2213
- >::type guard_t;
2214
-
2215
- guard_t guard(dst, get_allocator_ref());
2216
-
2217
- opt_copy(begin, end, dst, guard);
2218
-
2219
- guard.release();
2220
- }
2332
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2221
2333
 
2222
- template <typename Iterator, typename Guard>
2223
- void opt_copy(Iterator begin, Iterator end, pointer dst, Guard& guard)
2334
+ template <typename... Args>
2335
+ void resize_impl(size_type sz, Args&&... args)
2224
2336
  {
2225
- while (begin != end)
2337
+ const size_type old_sz = this->size();
2338
+ if (sz > old_sz)
2226
2339
  {
2227
- this->alloc_construct(dst++, *begin++);
2228
- guard.extend();
2229
- }
2230
- }
2340
+ const size_type n = sz - old_sz;
2231
2341
 
2232
- template <typename Guard>
2233
- void opt_copy(const_pointer begin, const_pointer end, pointer dst, Guard& guard)
2234
- {
2235
- // if trivial copy and default allocator, memcpy
2236
- boost::container::uninitialized_copy_alloc(get_allocator_ref(), begin, end, dst);
2237
- guard.extend();
2342
+ if (sz <= m_.capacity)
2343
+ {
2344
+ //Construct at back
2345
+ const size_type bfc = this->back_free_capacity();
2346
+ const size_type b = n < bfc ? n : bfc;
2347
+ construct_n(m_.buffer + m_.back_idx, b, boost::forward<Args>(args)...);
2348
+ m_.set_back_idx(m_.back_idx + b);
2349
+
2350
+ //Construct remaining at front
2351
+ const size_type f = n - b;
2352
+ construct_n(m_.buffer + m_.front_idx - f, f, boost::forward<Args>(args)...);
2353
+ m_.set_front_idx(m_.front_idx - f);
2354
+ }
2355
+ else
2356
+ {
2357
+ resize_back_slow_path(sz, n, boost::forward<Args>(args)...);
2358
+ }
2359
+ }
2360
+ else
2361
+ {
2362
+ const size_type n = old_sz - sz;
2363
+ const size_type new_bidx = m_.back_idx - n;
2364
+ destroy_elements(m_.buffer + new_bidx, m_.buffer + m_.back_idx);
2365
+ m_.set_back_idx(new_bidx);
2366
+ }
2238
2367
  }
2239
2368
 
2240
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2241
-
2242
2369
  template <typename... Args>
2243
2370
  void resize_front_impl(size_type sz , Args&&... args)
2244
2371
  {
2245
- if (sz > size())
2372
+ const size_type old_sz = this->size();
2373
+ if (sz > old_sz)
2246
2374
  {
2247
- const size_type n = sz - size();
2375
+ const size_type n = sz - old_sz;
2248
2376
 
2249
- if (sz <= front_capacity())
2377
+ if (sz <= this->front_capacity())
2250
2378
  {
2251
2379
  construct_n(m_.buffer + m_.front_idx - n, n, boost::forward<Args>(args)...);
2252
2380
  m_.set_front_idx(m_.front_idx - n);
@@ -2257,10 +2385,10 @@ class devector
2257
2385
  }
2258
2386
  }
2259
2387
  else {
2260
- while (this->size() > sz)
2261
- {
2262
- this->pop_front();
2263
- }
2388
+ const size_type n = old_sz - sz;
2389
+ const size_type new_fidx = m_.front_idx + n;
2390
+ destroy_elements(m_.buffer + m_.front_idx, m_.buffer + new_fidx);
2391
+ m_.set_front_idx(new_fidx);
2264
2392
  }
2265
2393
  }
2266
2394
 
@@ -2271,7 +2399,8 @@ class devector
2271
2399
  pointer new_buffer = allocate(new_capacity);
2272
2400
  allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2273
2401
 
2274
- const size_type new_old_elem_index = new_capacity - size();
2402
+ const size_type old_sz = this->size();
2403
+ const size_type new_old_elem_index = new_capacity - old_sz;
2275
2404
  const size_type new_elem_index = new_old_elem_index - n;
2276
2405
 
2277
2406
  detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, get_allocator_ref());
@@ -2284,18 +2413,19 @@ class devector
2284
2413
 
2285
2414
  m_.buffer = new_buffer;
2286
2415
  m_.set_capacity(new_capacity);
2287
- m_.set_back_idx(new_old_elem_index + m_.back_idx - m_.front_idx);
2288
2416
  m_.set_front_idx(new_elem_index);
2417
+ m_.set_back_idx(new_elem_index + old_sz + n);
2289
2418
  }
2290
2419
 
2291
2420
  template <typename... Args>
2292
2421
  void resize_back_impl(size_type sz, Args&&... args)
2293
2422
  {
2294
- if (sz > size())
2423
+ const size_type old_sz = this->size();
2424
+ if (sz > old_sz)
2295
2425
  {
2296
- const size_type n = sz - size();
2426
+ const size_type n = sz - old_sz;
2297
2427
 
2298
- if (sz <= back_capacity())
2428
+ if (sz <= this->back_capacity())
2299
2429
  {
2300
2430
  construct_n(m_.buffer + m_.back_idx, n, boost::forward<Args>(args)...);
2301
2431
  m_.set_back_idx(m_.back_idx + n);
@@ -2307,10 +2437,10 @@ class devector
2307
2437
  }
2308
2438
  else
2309
2439
  {
2310
- while (size() > sz)
2311
- {
2312
- pop_back();
2313
- }
2440
+ const size_type n = old_sz - sz;
2441
+ const size_type new_bidx = m_.back_idx - n;
2442
+ destroy_elements(m_.buffer + new_bidx, m_.buffer + m_.back_idx);
2443
+ m_.set_back_idx(new_bidx);
2314
2444
  }
2315
2445
  }
2316
2446
 
@@ -2334,111 +2464,6 @@ class devector
2334
2464
  m_.set_back_idx(m_.back_idx + n);
2335
2465
  }
2336
2466
 
2337
- template <typename... Args>
2338
- iterator emplace_slow_path(size_type new_elem_index, Args&&... args)
2339
- {
2340
- pointer position = begin() + new_elem_index;
2341
-
2342
- // prefer moving front to access memory forward if there are less elems to move
2343
- bool prefer_move_front = new_elem_index <= size()/2;
2344
-
2345
- if (front_free_capacity() && (!back_free_capacity() || prefer_move_front))
2346
- {
2347
- BOOST_ASSERT(size() >= 1);
2348
-
2349
- // move things closer to the front a bit
2350
-
2351
- // avoid invalidating any reference in args later
2352
- T tmp(boost::forward<Args>(args)...);
2353
-
2354
- // construct at front - 1 from front (no guard)
2355
- this->alloc_construct(begin() - 1, boost::move(*begin()));
2356
-
2357
- // move front half left
2358
- boost::move(begin() + 1, position, begin());
2359
- --m_.front_idx;
2360
-
2361
- // move assign new elem before pos
2362
- --position;
2363
- *position = boost::move(tmp);
2364
-
2365
- return position;
2366
- }
2367
- else if (back_free_capacity()) {
2368
- BOOST_ASSERT(size() >= 1);
2369
-
2370
- // move things closer to the end a bit
2371
-
2372
- // avoid invalidating any reference in args later
2373
- T tmp(boost::forward<Args>(args)...);
2374
-
2375
- // construct at back + 1 from back (no guard)
2376
- this->alloc_construct(end(), boost::move(back()));
2377
-
2378
- // move back half right
2379
- boost::container::move_backward(position, end() - 1, end());
2380
- ++m_.back_idx;
2381
-
2382
- // move assign new elem to pos
2383
- *position = boost::move(tmp);
2384
-
2385
- return position;
2386
- }
2387
- else
2388
- {
2389
- return emplace_reallocating_slow_path(prefer_move_front, new_elem_index, boost::forward<Args>(args)...);
2390
- }
2391
- }
2392
-
2393
- template <typename... Args>
2394
- pointer emplace_reallocating_slow_path(bool make_front_free, size_type new_elem_index, Args&&... args)
2395
- {
2396
- // reallocate
2397
- size_type new_capacity = calculate_new_capacity(capacity() + 1);
2398
- pointer new_buffer = allocate(new_capacity);
2399
-
2400
- // guard allocation
2401
- allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2402
-
2403
- size_type new_front_index = (make_front_free)
2404
- ? new_capacity - back_free_capacity() - size() - 1
2405
- : m_.front_idx;
2406
-
2407
- iterator new_begin = new_buffer + new_front_index;
2408
- iterator new_position = new_begin + new_elem_index;
2409
- iterator old_position = begin() + new_elem_index;
2410
-
2411
- // construct new element (and guard it)
2412
- this->alloc_construct(new_position, boost::forward<Args>(args)...);
2413
-
2414
- detail::construction_guard<allocator_type> second_half_guard(new_position, get_allocator_ref());
2415
- second_half_guard.extend();
2416
-
2417
- // move front-pos (possibly guarded)
2418
- detail::construction_guard<allocator_type> first_half_guard(new_begin, get_allocator_ref());
2419
- opt_move_or_copy(begin(), old_position, new_begin, first_half_guard);
2420
-
2421
- // move pos+1-end (possibly guarded)
2422
- opt_move_or_copy(old_position, end(), new_position + 1, second_half_guard);
2423
-
2424
- // cleanup
2425
- destroy_elements(begin(), end());
2426
- deallocate_buffer();
2427
-
2428
- // release alloc and other guards
2429
- second_half_guard.release();
2430
- first_half_guard.release();
2431
- new_buffer_guard.release();
2432
-
2433
- // rebind members
2434
- m_.set_capacity(new_capacity);
2435
- m_.buffer = new_buffer;
2436
- m_.set_back_idx(new_front_index + size() + 1);
2437
- m_.set_front_idx(new_front_index);
2438
-
2439
- return new_position;
2440
- }
2441
-
2442
2467
  #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2443
2468
 
2444
2469
  #define BOOST_CONTAINER_DEVECTOR_SLOW_PATH(N) \
@@ -2534,135 +2559,22 @@ class devector
2534
2559
  m_.set_back_idx(m_.back_idx + n);\
2535
2560
  }\
2536
2561
  \
2537
- BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2538
- iterator emplace_slow_path(size_type new_elem_index BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2539
- {\
2540
- pointer position = begin() + new_elem_index;\
2541
- \
2542
- bool prefer_move_front = new_elem_index <= size()/2;\
2543
- \
2544
- if (front_free_capacity() && (!back_free_capacity() || prefer_move_front))\
2545
- {\
2546
- BOOST_ASSERT(size() >= 1);\
2547
- typename dtl::aligned_storage<sizeof(T), dtl::alignment_of<T>::value>::type v;\
2548
- T *vp = move_detail::force_ptr<T *>(v.data);\
2549
- allocator_traits_type::construct(get_stored_allocator(), vp BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2550
- T &tmp = *vp;\
2551
- dtl::value_destructor<allocator_type> on_exit(get_stored_allocator(), tmp); (void)on_exit;\
2552
- \
2553
- this->alloc_construct(begin() - 1, boost::move(*begin()));\
2554
- boost::move(begin() + 1, position, begin());\
2555
- --m_.front_idx;\
2556
- --position;\
2557
- *position = boost::move(tmp);\
2558
- return position;\
2559
- }\
2560
- else if (back_free_capacity()) {\
2561
- BOOST_ASSERT(size() >= 1);\
2562
- typename dtl::aligned_storage<sizeof(T), dtl::alignment_of<T>::value>::type v;\
2563
- T *vp = move_detail::force_ptr<T *>(v.data);\
2564
- allocator_traits_type::construct(get_stored_allocator(), vp BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2565
- T &tmp = *vp;\
2566
- dtl::value_destructor<allocator_type> on_exit(get_stored_allocator(), tmp); (void)on_exit;\
2567
- this->alloc_construct(end(), boost::move(back()));\
2568
- boost::container::move_backward(position, end() - 1, end());\
2569
- ++m_.back_idx;\
2570
- *position = boost::move(tmp);\
2571
- return position;\
2572
- }\
2573
- else {\
2574
- return emplace_reallocating_slow_path(prefer_move_front, new_elem_index BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2575
- }\
2576
- }\
2577
- \
2578
- BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2579
- pointer emplace_reallocating_slow_path(bool make_front_free, size_type new_elem_index BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2580
- {\
2581
- size_type new_capacity = calculate_new_capacity(capacity() + 1);\
2582
- pointer new_buffer = allocate(new_capacity);\
2583
- allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\
2584
- size_type new_front_index = (make_front_free)\
2585
- ? new_capacity - back_free_capacity() - size() - 1\
2586
- : m_.front_idx;\
2587
- iterator new_begin = new_buffer + new_front_index;\
2588
- iterator new_position = new_begin + new_elem_index;\
2589
- iterator old_position = begin() + new_elem_index;\
2590
- this->alloc_construct(new_position BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2591
- detail::construction_guard<allocator_type> second_half_guard(new_position, get_allocator_ref());\
2592
- second_half_guard.extend();\
2593
- detail::construction_guard<allocator_type> first_half_guard(new_begin, get_allocator_ref());\
2594
- opt_move_or_copy(begin(), old_position, new_begin, first_half_guard);\
2595
- opt_move_or_copy(old_position, end(), new_position + 1, second_half_guard);\
2596
- destroy_elements(begin(), end());\
2597
- deallocate_buffer();\
2598
- second_half_guard.release();\
2599
- first_half_guard.release();\
2600
- new_buffer_guard.release();\
2601
- m_.set_capacity(new_capacity);\
2602
- m_.buffer = new_buffer;\
2603
- m_.set_back_idx(new_front_index + size() + 1);\
2604
- m_.set_front_idx(new_front_index);\
2605
- return new_position;\
2606
- }\
2607
2562
  //
2608
2563
  BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_SLOW_PATH)
2609
2564
  #undef BOOST_CONTAINER_DEVECTOR_SLOW_PATH
2610
2565
 
2611
- #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2612
- /*
2613
- void unsafe_uninitialized_grow_front(size_type n)
2614
- {
2615
- BOOST_ASSERT(n >= size());
2616
-
2617
- size_type need = n - size();
2618
-
2619
- if (need > front_free_capacity())
2620
- {
2621
- reallocate_at(n + back_free_capacity(), need);
2622
- }
2623
-
2624
- m_.set_front_idx(m_.front_idx - need);
2625
- }
2626
-
2627
- void unsafe_uninitialized_shrink_front(size_type n)
2628
- {
2629
- BOOST_ASSERT(n <= size());
2630
-
2631
- size_type doesnt_need = size() - n;
2632
- m_.set_front_idx(m_.front_idx + doesnt_need);
2633
- }
2634
-
2635
- void unsafe_uninitialized_grow_back(size_type n)
2636
- {
2637
- BOOST_ASSERT(n >= size());
2638
-
2639
- size_type need = n - size();
2640
-
2641
- if (need > back_free_capacity())
2642
- {
2643
- reallocate_at(n + front_free_capacity(), front_free_capacity());
2644
- }
2645
-
2646
- m_.set_back_idx(m_.back_idx + need);
2647
- }
2648
-
2649
- void unsafe_uninitialized_shrink_back(size_type n)
2650
- {
2651
- BOOST_ASSERT(n <= size());
2652
-
2653
- size_type doesnt_need = size() - n;
2654
- m_.set_back_idx(m_.back_idx - doesnt_need);
2655
- }
2656
- */
2566
+ #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2657
2567
 
2658
2568
  void reallocate_at(size_type new_capacity, size_type buffer_offset)
2659
2569
  {
2660
2570
  pointer new_buffer = allocate(new_capacity);
2661
- allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2662
-
2663
- buffer_move_or_copy(new_buffer + buffer_offset);
2664
-
2665
- new_buffer_guard.release();
2571
+ {
2572
+ allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2573
+ boost::container::uninitialized_move_alloc(get_allocator_ref(), this->begin(), this->end(), new_buffer + buffer_offset);
2574
+ new_buffer_guard.release();
2575
+ }
2576
+ destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
2577
+ deallocate_buffer();
2666
2578
 
2667
2579
  m_.buffer = new_buffer;
2668
2580
  //Safe cast, allocate() will handle stored_size_type overflow
@@ -2676,154 +2588,129 @@ class devector
2676
2588
  template <typename ForwardIterator>
2677
2589
  iterator insert_range(const_iterator position, ForwardIterator first, ForwardIterator last)
2678
2590
  {
2679
- size_type n = boost::container::iterator_udistance(first, last);
2591
+ BOOST_ASSERT(position >= begin());
2592
+ BOOST_ASSERT(position <= end());
2593
+ typedef dtl::insert_range_proxy<allocator_type, ForwardIterator> proxy_t;
2680
2594
 
2681
- if (position == end() && back_free_capacity() >= n) {// fast path
2682
- iterator r(this->end());
2683
- boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->raw_end());
2684
- m_.set_back_idx(m_.back_idx + n);
2685
- return r;
2686
- }
2687
- else if (position == begin() && front_free_capacity() >= n) { // secondary fast path
2688
- boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->raw_begin() - n);
2689
- m_.set_front_idx(m_.front_idx - n);
2690
- return begin();
2595
+ size_type const n = boost::container::iterator_udistance(first, last);
2596
+ bool prefer_move_back;
2597
+ if (BOOST_UNLIKELY(!n)) {
2598
+ return begin() + size_type(position - cbegin());
2691
2599
  }
2692
- else {
2693
- return insert_range_slow_path(position, first, last);
2600
+ else if (position == end()) {
2601
+ if(back_free_capacity() >= n) // fast path
2602
+ {
2603
+ iterator r(this->end());
2604
+ boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_end());
2605
+ m_.set_back_idx(m_.back_idx + n);
2606
+ return r;
2607
+ }
2608
+ prefer_move_back = true;
2694
2609
  }
2695
- }
2696
-
2697
- template <typename ForwardIterator>
2698
- iterator insert_range_slow_path(const_iterator position, ForwardIterator first, ForwardIterator last)
2699
- {
2700
- size_type n = boost::container::iterator_udistance(first, last);
2701
- size_type index = size_type(position - begin());
2702
-
2703
- if (front_free_capacity() + back_free_capacity() >= n) {
2704
- // if we move enough, it can be done without reallocation
2705
-
2706
- iterator middle = begin() + index;
2707
- n -= insert_range_slow_path_near_front(middle, first, n);
2708
-
2709
- if (n) {
2710
- insert_range_slow_path_near_back(middle, first, n);
2610
+ else if (position == begin()) {
2611
+ if(front_free_capacity() >= n) {// secondary fast path
2612
+ boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_begin() - n);
2613
+ m_.set_front_idx(m_.front_idx - n);
2614
+ return begin();
2711
2615
  }
2712
-
2713
- BOOST_ASSERT(first == last);
2714
- return begin() + index;
2616
+ prefer_move_back = false;
2715
2617
  }
2716
- else {
2717
- const bool prefer_move_front = 2 * index <= size();
2718
- return insert_range_reallocating_slow_path(prefer_move_front, index, first, n);
2618
+ else{
2619
+ iterator nonconst_pos = unconst_iterator(position);
2620
+ prefer_move_back = should_move_back(position);
2621
+
2622
+ if(prefer_move_back){
2623
+ if(back_free_capacity() >= n){
2624
+ boost::container::expand_forward_and_insert_nonempty_middle_alloc
2625
+ ( get_allocator_ref()
2626
+ , boost::movelib::to_raw_pointer(nonconst_pos)
2627
+ , this->priv_raw_end()
2628
+ , n, proxy_t(first));
2629
+ m_.set_back_idx(m_.back_idx + n);
2630
+ return nonconst_pos;
2631
+ }
2632
+ }
2633
+ else{
2634
+ if (front_free_capacity() >= n){
2635
+ boost::container::expand_backward_and_insert_nonempty_middle_alloc
2636
+ ( get_allocator_ref()
2637
+ , this->priv_raw_begin()
2638
+ , boost::movelib::to_raw_pointer(nonconst_pos)
2639
+ , n, proxy_t(first));
2640
+ m_.set_front_idx(m_.front_idx - n);
2641
+ return (nonconst_pos -= n);
2642
+ }
2643
+ }
2719
2644
  }
2720
- }
2721
-
2722
- template <typename Iterator>
2723
- size_type insert_range_slow_path_near_front(iterator position, Iterator& first, size_type n)
2724
- {
2725
- size_type n_front = dtl::min_value(front_free_capacity(), n);
2726
- iterator new_begin = begin() - n_front;
2727
- iterator ctr_pos = new_begin;
2728
- detail::construction_guard<allocator_type> ctr_guard(ctr_pos, get_allocator_ref());
2729
-
2730
- while (ctr_pos != begin()) {
2731
- this->alloc_construct(ctr_pos++, *(first++));
2732
- ctr_guard.extend();
2645
+ return this->insert_range_slow_path(position, n, proxy_t(first));
2646
+ }
2647
+
2648
+ template <class InsertionProxy>
2649
+ BOOST_CONTAINER_NOINLINE iterator insert_range_slow_path
2650
+ (const_iterator p, const size_type n, const InsertionProxy proxy)
2651
+ {
2652
+ size_type const back_free_cap = back_free_capacity();
2653
+ size_type const front_free_cap = front_free_capacity();
2654
+ size_type const free_cap = front_free_cap + back_free_cap;
2655
+ size_type const index = size_type(p - cbegin());
2656
+
2657
+ size_type const cap = m_.capacity;
2658
+ //Test if enough free memory would be left
2659
+ if (free_cap >= n && (free_cap - n) >= cap/devector_min_free_fraction) {
2660
+ //Make sure relocation is happening because there was no enough space
2661
+ size_type const old_size = this->size();
2662
+ BOOST_ASSERT(should_move_back(p) ? (back_free_cap < n) : (front_free_cap < n));
2663
+
2664
+ T* const raw_pos = const_cast<T*>(boost::movelib::to_raw_pointer(p));
2665
+ size_type const new_size = old_size + n;
2666
+ size_type const new_front_idx = (cap - new_size) / 2u;
2667
+
2668
+ T* const raw_beg = this->priv_raw_begin();
2669
+ T* const new_raw_beg = raw_beg - std::ptrdiff_t(m_.front_idx - new_front_idx);
2670
+ m_.back_idx = 0u;
2671
+ m_.front_idx = 0u;
2672
+ boost::container::expand_backward_forward_and_insert_alloc
2673
+ (raw_beg, old_size, new_raw_beg, raw_pos, n, proxy, get_allocator_ref());
2674
+ m_.set_front_idx(new_front_idx);
2675
+ m_.set_back_idx(new_front_idx + new_size);
2733
2676
  }
2677
+ else {
2678
+ // reallocate
2679
+ const size_type new_capacity = calculate_new_capacity(m_.capacity + n);
2680
+ pointer new_buffer = allocate(new_capacity);
2734
2681
 
2735
- boost::movelib::rotate_gcd(new_begin, ctr_pos, position);
2736
- m_.set_front_idx(m_.front_idx - n_front);
2737
-
2738
- ctr_guard.release();
2682
+ // guard allocation
2683
+ allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2739
2684
 
2740
- BOOST_ASSERT(invariants_ok());
2685
+ size_type const old_size = this->size();
2686
+ const size_type new_front_index = (new_capacity - old_size - n) / 2u;
2741
2687
 
2742
- return n_front;
2743
- }
2688
+ T* const raw_pos = const_cast<T*>(boost::movelib::to_raw_pointer(p));
2689
+ T* const raw_new_start = const_cast<T*>(boost::movelib::to_raw_pointer(new_buffer)) + new_front_index;
2744
2690
 
2745
- template <typename Iterator>
2746
- size_type insert_range_slow_path_near_back(iterator position, Iterator& first, size_type n)
2747
- {
2748
- const size_type n_back = dtl::min_value(back_free_capacity(), n);
2749
- iterator ctr_pos = end();
2691
+ boost::container::uninitialized_move_and_insert_alloc
2692
+ (get_allocator_ref(), this->priv_raw_begin(), raw_pos, this->priv_raw_end(), raw_new_start, n, proxy);
2693
+ new_buffer_guard.release();
2750
2694
 
2751
- detail::construction_guard<allocator_type> ctr_guard(ctr_pos, get_allocator_ref());
2695
+ // cleanup
2696
+ destroy_elements(begin(), end());
2697
+ deallocate_buffer();
2752
2698
 
2753
- for (size_type i = 0; i < n_back; ++i) {
2754
- this->alloc_construct(ctr_pos++, *first++);
2755
- ctr_guard.extend();
2699
+ // rebind members
2700
+ m_.set_capacity(new_capacity);
2701
+ m_.buffer = new_buffer;
2702
+ m_.set_back_idx(new_front_index + old_size + n);
2703
+ m_.set_front_idx(new_front_index);
2756
2704
  }
2757
-
2758
- boost::movelib::rotate_gcd(position, end(), ctr_pos);
2759
- m_.set_back_idx(m_.back_idx + n_back);
2760
-
2761
- ctr_guard.release();
2762
-
2763
- BOOST_ASSERT(invariants_ok());
2764
-
2765
- return n_back;
2705
+ return begin() + index;
2766
2706
  }
2767
2707
 
2768
- template <typename Iterator>
2769
- iterator insert_range_reallocating_slow_path
2770
- (bool make_front_free, size_type new_elem_index, Iterator elems, size_type n)
2771
- {
2772
- // reallocate
2773
- const size_type new_capacity = calculate_new_capacity(capacity() + n);
2774
- pointer new_buffer = allocate(new_capacity);
2775
-
2776
- // guard allocation
2777
- allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2778
-
2779
- const size_type new_front_index = (make_front_free)
2780
- ? new_capacity - back_free_capacity() - size() - n
2781
- : m_.front_idx;
2782
-
2783
- const iterator new_begin = new_buffer + new_front_index;
2784
- const iterator new_position = new_begin + new_elem_index;
2785
- const iterator old_position = begin() + new_elem_index;
2786
-
2787
- // construct new element (and guard it)
2788
- iterator second_half_position = new_position;
2789
- detail::construction_guard<allocator_type> second_half_guard(second_half_position, get_allocator_ref());
2790
-
2791
- for (size_type i = 0; i < n; ++i) {
2792
- this->alloc_construct(second_half_position++, *(elems++));
2793
- second_half_guard.extend();
2794
- }
2795
-
2796
- // move front-pos (possibly guarded)
2797
- detail::construction_guard<allocator_type> first_half_guard(new_begin, get_allocator_ref());
2798
- opt_move_or_copy(begin(), old_position, new_begin, first_half_guard);
2799
-
2800
- // move pos+1-end (possibly guarded)
2801
- opt_move_or_copy(old_position, end(), second_half_position, second_half_guard);
2802
-
2803
- // cleanup
2804
- destroy_elements(begin(), end());
2805
- deallocate_buffer();
2806
-
2807
- // release alloc and other guards
2808
- second_half_guard.release();
2809
- first_half_guard.release();
2810
- new_buffer_guard.release();
2811
-
2812
- // rebind members
2813
- m_.set_capacity(new_capacity);
2814
- m_.buffer = new_buffer;
2815
- m_.set_back_idx(new_front_index + size() + n);
2816
- m_.set_front_idx(new_front_index);
2817
-
2818
- return new_position;
2819
- }
2820
2708
 
2821
2709
  template <typename Iterator>
2822
2710
  void construct_from_range(Iterator begin, Iterator end)
2823
2711
  {
2824
2712
  allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
2825
- opt_copy(begin, end, m_.buffer);
2826
-
2713
+ boost::container::uninitialized_copy_alloc(get_allocator_ref(), begin, end, m_.buffer);
2827
2714
  buffer_guard.release();
2828
2715
  }
2829
2716
 
@@ -2834,9 +2721,7 @@ class devector
2834
2721
 
2835
2722
  pointer new_buffer = n ? allocate(n) : pointer();
2836
2723
  allocation_guard new_buffer_guard(new_buffer, n, get_allocator_ref());
2837
-
2838
- opt_copy(first, last, new_buffer);
2839
-
2724
+ boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, new_buffer);
2840
2725
  destroy_elements(begin(), end());
2841
2726
  deallocate_buffer();
2842
2727
 
@@ -2859,10 +2744,10 @@ class devector
2859
2744
  {
2860
2745
  const size_type n = boost::container::iterator_udistance(first, last);
2861
2746
 
2862
- BOOST_ASSERT(capacity() >= n);
2747
+ BOOST_ASSERT(m_.capacity >= n);
2863
2748
  boost::container::uninitialized_copy_alloc_n
2864
- ( get_allocator_ref(), boost::movelib::iterator_to_raw_pointer(first)
2865
- , n, boost::movelib::iterator_to_raw_pointer(m_.buffer));
2749
+ ( get_allocator_ref(), first
2750
+ , n, boost::movelib::to_raw_pointer(m_.buffer));
2866
2751
  m_.front_idx = 0;
2867
2752
  m_.set_back_idx(n);
2868
2753
  }
@@ -2884,7 +2769,7 @@ class devector
2884
2769
 
2885
2770
  detail::construction_guard<allocator_type> back_guard(pos, get_allocator_ref());
2886
2771
 
2887
- iterator capacity_end = m_.buffer + capacity();
2772
+ iterator capacity_end = m_.buffer + m_.capacity;
2888
2773
  while (first != last && pos != capacity_end) {
2889
2774
  this->alloc_construct(pos++, *first++);
2890
2775
  back_guard.extend();
@@ -2897,7 +2782,7 @@ class devector
2897
2782
  back_guard.release();
2898
2783
 
2899
2784
  m_.front_idx = 0;
2900
- m_.set_back_idx(size_type(pos - begin()));
2785
+ m_.set_back_idx(pos_to_index(pos));
2901
2786
  return first;
2902
2787
  }
2903
2788
 
@@ -2905,31 +2790,30 @@ class devector
2905
2790
  BOOST_CONTAINER_FORCEINLINE void overwrite_buffer(ForwardIterator first, ForwardIterator last)
2906
2791
  {
2907
2792
  this->overwrite_buffer_impl(first, last,
2908
- dtl::bool_<dtl::is_trivially_destructible<T>::value>());
2793
+ dtl::bool_<dtl::is_trivially_destructible<T>::value>());
2909
2794
  }
2910
2795
 
2911
2796
  bool invariants_ok()
2912
2797
  {
2913
- return (!m_.capacity || m_.buffer)
2914
- && m_.front_idx <= m_.back_idx
2915
- && m_.back_idx <= m_.capacity;
2798
+ return (! m_.capacity || m_.buffer )
2799
+ && m_.front_idx <= m_.back_idx
2800
+ && m_.back_idx <= m_.capacity;
2916
2801
  }
2917
2802
 
2918
2803
  struct impl : allocator_type
2919
2804
  {
2920
- private:
2921
- impl(const impl &i);
2805
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(impl)
2922
2806
 
2923
2807
  public:
2924
2808
  allocator_type &get_al()
2925
- { return *this; }
2809
+ { return *this; }
2926
2810
 
2927
2811
  static pointer do_allocate(allocator_type &a, size_type cap)
2928
2812
  {
2929
2813
  if (cap) {
2930
2814
  //First detect overflow on smaller stored_size_types
2931
2815
  if (cap > stored_size_type(-1)){
2932
- boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
2816
+ boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
2933
2817
  }
2934
2818
  return allocator_traits_type::allocate(a, cap);
2935
2819
  }
@@ -2952,58 +2836,92 @@ class devector
2952
2836
  #endif
2953
2837
  {}
2954
2838
 
2955
- impl(const allocator_type &a, size_type f, size_type b, size_type c)
2956
- : allocator_type(a), buffer(do_allocate(get_al(), c))
2839
+ impl(reserve_uninitialized_t, const allocator_type& a, size_type c)
2840
+ : allocator_type(a), buffer(do_allocate(get_al(), c) )
2957
2841
  //static cast sizes, as the allocation function will take care of overflows
2958
- , front_idx(static_cast<stored_size_type>(f))
2959
- , back_idx(static_cast<stored_size_type>(b))
2842
+ , front_idx(static_cast<stored_size_type>(0u))
2843
+ , back_idx(static_cast<stored_size_type>(c))
2960
2844
  , capacity(static_cast<stored_size_type>(c))
2961
2845
  #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2962
2846
  , capacity_alloc_count(size_type(buffer != pointer()))
2963
2847
  #endif
2964
2848
  {}
2965
2849
 
2966
- impl(const allocator_type &a, pointer p, size_type f, size_type b, size_type c)
2967
- : allocator_type(a), buffer(p)
2850
+ impl(reserve_only_tag_t, const allocator_type &a, size_type const ffc, size_type const bfc)
2851
+ : allocator_type(a), buffer(do_allocate(get_al(), ffc+bfc) )
2968
2852
  //static cast sizes, as the allocation function will take care of overflows
2969
- , front_idx(static_cast<stored_size_type>(f))
2970
- , back_idx(static_cast<stored_size_type>(b))
2853
+ , front_idx(static_cast<stored_size_type>(ffc))
2854
+ , back_idx(static_cast<stored_size_type>(ffc))
2855
+ , capacity(static_cast<stored_size_type>(ffc + bfc))
2856
+ #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2857
+ , capacity_alloc_count(size_type(buffer != pointer()))
2858
+ #endif
2859
+ {}
2860
+
2861
+ impl(reserve_only_tag_t, const allocator_type &a, size_type const c)
2862
+ : allocator_type(a), buffer(do_allocate(get_al(), c) )
2863
+ //static cast sizes, as the allocation function will take care of overflows
2864
+ , front_idx(static_cast<stored_size_type>(c/2u))
2865
+ , back_idx(static_cast<stored_size_type>(c/2u))
2971
2866
  , capacity(static_cast<stored_size_type>(c))
2972
2867
  #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2973
- , capacity_alloc_count(0)
2868
+ , capacity_alloc_count(size_type(buffer != pointer()))
2974
2869
  #endif
2975
2870
  {}
2976
2871
 
2977
- impl(BOOST_RV_REF(allocator_type) a, pointer p, size_type f, size_type b, size_type c)
2978
- : allocator_type(boost::move(a)), buffer(p)
2872
+ impl(review_implementation_t, const allocator_type &a, pointer p, size_type fi, size_type bi, size_type c)
2873
+ : allocator_type(a), buffer(p)
2979
2874
  //static cast sizes, as the allocation function will take care of overflows
2980
- , front_idx(static_cast<stored_size_type>(f))
2981
- , back_idx(static_cast<stored_size_type>(b))
2875
+ , front_idx(static_cast<stored_size_type>(fi))
2876
+ , back_idx(static_cast<stored_size_type>(bi))
2982
2877
  , capacity(static_cast<stored_size_type>(c))
2983
2878
  #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2984
2879
  , capacity_alloc_count(0)
2985
2880
  #endif
2986
2881
  {}
2987
2882
 
2988
- void set_back_idx(size_type bi)
2989
- { back_idx = static_cast<stored_size_type>(bi);}
2883
+ impl(BOOST_RV_REF(impl) m)
2884
+ : allocator_type(BOOST_MOVE_BASE(allocator_type, m))
2885
+ , buffer(static_cast<impl&>(m).buffer)
2886
+ , front_idx(static_cast<impl&>(m).front_idx)
2887
+ , back_idx(static_cast<impl&>(m).back_idx)
2888
+ , capacity(static_cast<impl&>(m).capacity)
2889
+ #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2890
+ , capacity_alloc_count(0)
2891
+ #endif
2892
+ {
2893
+ impl &i = static_cast<impl&>(m);
2894
+ // buffer is already acquired, reset rhs
2895
+ i.capacity = 0u;
2896
+ i.buffer = pointer();
2897
+ i.front_idx = 0;
2898
+ i.back_idx = 0;
2899
+ }
2990
2900
 
2991
- void set_front_idx(size_type fi)
2992
- { front_idx = static_cast<stored_size_type>(fi);}
2901
+ BOOST_CONTAINER_FORCEINLINE void set_back_idx(size_type bi)
2902
+ {
2903
+ back_idx = static_cast<stored_size_type>(bi);
2904
+ }
2993
2905
 
2994
- void set_capacity(size_type c)
2995
- { capacity = static_cast<stored_size_type>(c);}
2906
+ BOOST_CONTAINER_FORCEINLINE void set_front_idx(size_type fi)
2907
+ {
2908
+ front_idx = static_cast<stored_size_type>(fi);
2909
+ }
2996
2910
 
2997
- pointer buffer;
2998
- stored_size_type front_idx;
2999
- stored_size_type back_idx;
3000
- stored_size_type capacity;
2911
+ BOOST_CONTAINER_FORCEINLINE void set_capacity(size_type c)
2912
+ {
2913
+ capacity = static_cast<stored_size_type>(c);
2914
+ }
2915
+
2916
+ pointer buffer;
2917
+ stored_size_type front_idx;
2918
+ stored_size_type back_idx;
2919
+ stored_size_type capacity;
3001
2920
  #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
3002
2921
  size_type capacity_alloc_count;
3003
2922
  #endif
3004
2923
  } m_;
3005
2924
 
3006
-
3007
2925
  #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
3008
2926
  public:
3009
2927
  void reset_alloc_stats()
@@ -3023,6 +2941,25 @@ class devector
3023
2941
 
3024
2942
  }} // namespace boost::container
3025
2943
 
2944
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2945
+
2946
+ namespace boost {
2947
+
2948
+ //!has_trivial_destructor_after_move<> == true_type
2949
+ //!specialization for optimizations
2950
+ template <class T, class Allocator, class Options>
2951
+ struct has_trivial_destructor_after_move<boost::container::devector<T, Allocator, Options> >
2952
+ {
2953
+ typedef typename boost::container::devector<T, Allocator, Options>::allocator_type allocator_type;
2954
+ typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
2955
+ static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
2956
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
2957
+ };
2958
+
2959
+ }
2960
+
2961
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2962
+
3026
2963
  #include <boost/container/detail/config_end.hpp>
3027
2964
 
3028
2965
  #endif // BOOST_CONTAINER_DEVECTOR_HPP