passenger 6.2.1 → 6.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +37 -15
- data/build/cxx_tests.rb +2 -0
- data/build/support/cxx_dependency_map.rb +3 -63
- data/src/agent/Core/Config.h +1 -1
- data/src/agent/Core/Controller/Config.h +1 -1
- data/src/agent/Shared/ApiServerUtils.h +1 -1
- data/src/agent/Watchdog/Config.h +1 -1
- data/src/apache2_module/Hooks.cpp +13 -0
- data/src/apache2_module/Utils.h +14 -0
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/FileTools/FileManip.cpp +27 -3
- data/src/cxx_supportlib/InstanceDirectory.h +30 -3
- data/src/cxx_supportlib/ServerKit/Errors.h +1 -1
- data/src/cxx_supportlib/ServerKit/HttpHeaderParser.h +1 -1
- data/src/cxx_supportlib/ServerKit/HttpHeaderParserState.h +1 -1
- data/src/cxx_supportlib/ServerKit/HttpRequest.h +1 -1
- data/src/cxx_supportlib/ServerKit/llerrors.h +3 -3
- data/src/cxx_supportlib/ServerKit/llversion.h +1 -1
- data/src/cxx_supportlib/{ServerKit/llhttp_api.c → vendor-copy/llhttp/api.c} +30 -23
- data/src/cxx_supportlib/{ServerKit → vendor-copy/llhttp}/llhttp.c +1756 -1645
- data/src/cxx_supportlib/{ServerKit → vendor-copy/llhttp}/llhttp.h +35 -13
- data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/classification.hpp +19 -0
- data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/formatter.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/trim_all.hpp +0 -2
- data/src/cxx_supportlib/vendor-modified/boost/assert.hpp +20 -13
- data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_x86.hpp +2 -2
- data/src/cxx_supportlib/vendor-modified/boost/atomic/thread_pause.hpp +4 -0
- data/src/cxx_supportlib/vendor-modified/boost/bind/mem_fn.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/circular_buffer/debug.hpp +4 -0
- data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx03.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx11.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx14.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx17.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx20.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx23.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/auto_link.hpp +6 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang_version.hpp +10 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/compiler/visualc.hpp +5 -3
- data/src/cxx_supportlib/vendor-modified/boost/config/detail/cxx_composite.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/config/workaround.hpp +5 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/adaptive_pool.hpp +57 -53
- data/src/cxx_supportlib/vendor-modified/boost/container/allocator.hpp +10 -10
- data/src/cxx_supportlib/vendor-modified/boost/container/allocator_traits.hpp +34 -2
- data/src/cxx_supportlib/vendor-modified/boost/container/container_fwd.hpp +14 -2
- data/src/cxx_supportlib/vendor-modified/boost/container/deque.hpp +176 -2287
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/adaptive_node_pool.hpp +13 -9
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/adaptive_node_pool_impl.hpp +186 -70
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/algorithm.hpp +2 -2
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/aligned_allocation.hpp +149 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/alloc_helpers.hpp +35 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/alloc_lib.h +1 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/bit_utilities.hpp +133 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/compare_functors.hpp +18 -3
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_begin.hpp +5 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_end.hpp +4 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/container_rebind.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/copy_move_algo.hpp +20 -10
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/deque_impl.hpp +2744 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/dispatch_uses_allocator.hpp +202 -104
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/dlmalloc.hpp +5 -4
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/flat_tree.hpp +161 -85
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/is_constructible.hpp +180 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/iterators.hpp +3 -2
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/math_functions.hpp +12 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/mpl.hpp +16 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/mutex.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/next_capacity.hpp +9 -1
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_pool.hpp +18 -14
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_pool_impl.hpp +256 -41
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/operator_new_helpers.hpp +75 -24
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/pair.hpp +1 -56
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/placement_new.hpp +16 -3
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/pool_common_alloc.hpp +1 -7
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/range_utils.hpp +196 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/std_fwd.hpp +33 -1
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/tree.hpp +124 -69
- data/src/cxx_supportlib/vendor-modified/boost/container/detail/workaround.hpp +109 -7
- data/src/cxx_supportlib/vendor-modified/boost/container/devector.hpp +168 -162
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/nest.hpp +2978 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/pmr/nest.hpp +45 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_all_of.hpp +43 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_any_of.hpp +42 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_copy.hpp +229 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_copy_if.hpp +270 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_copy_n.hpp +308 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_count.hpp +101 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_count_if.hpp +100 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_equal.hpp +268 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_fill.hpp +101 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_fill_n.hpp +171 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_find.hpp +110 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_find_if.hpp +110 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_find_if_not.hpp +43 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_find_last.hpp +179 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_find_last_if.hpp +179 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_find_last_if_not.hpp +43 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_for_each.hpp +92 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_generate.hpp +90 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_generate_n.hpp +162 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_is_partitioned.hpp +46 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_is_sorted.hpp +49 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_is_sorted_until.hpp +169 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_iterator_traits.hpp +382 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_merge.hpp +428 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_mismatch.hpp +350 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_none_of.hpp +98 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_partition.hpp +296 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_partition_copy.hpp +105 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_partition_point.hpp +116 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_remove.hpp +57 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_remove_copy.hpp +207 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_remove_copy_if.hpp +223 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_remove_if.hpp +57 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_replace.hpp +90 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_replace_if.hpp +90 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_reverse.hpp +245 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_reverse_copy.hpp +229 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_search.hpp +211 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_search_n.hpp +476 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_set_difference.hpp +300 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_set_intersection.hpp +287 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_set_symmetric_difference.hpp +306 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_set_union.hpp +294 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_stable_partition.hpp +153 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_swap_ranges.hpp +92 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/segmented_transform.hpp +93 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/experimental/wrapped_iterator.hpp +142 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/flat_map.hpp +642 -417
- data/src/cxx_supportlib/vendor-modified/boost/container/flat_set.hpp +141 -30
- data/src/cxx_supportlib/vendor-modified/boost/container/hub.hpp +2426 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/list.hpp +65 -57
- data/src/cxx_supportlib/vendor-modified/boost/container/map.hpp +247 -68
- data/src/cxx_supportlib/vendor-modified/boost/container/new_allocator.hpp +7 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/node_allocator.hpp +39 -33
- data/src/cxx_supportlib/vendor-modified/boost/container/options.hpp +156 -23
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/global_resource.hpp +3 -3
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/hub.hpp +43 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/memory_resource.hpp +5 -3
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/monotonic_buffer_resource.hpp +1 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/polymorphic_allocator.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/resource_adaptor.hpp +4 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/pmr/segtor.hpp +45 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/scoped_allocator.hpp +5 -4
- data/src/cxx_supportlib/vendor-modified/boost/container/segtor.hpp +905 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/set.hpp +148 -35
- data/src/cxx_supportlib/vendor-modified/boost/container/slist.hpp +59 -52
- data/src/cxx_supportlib/vendor-modified/boost/container/small_vector.hpp +632 -5
- data/src/cxx_supportlib/vendor-modified/boost/container/stable_vector.hpp +66 -60
- data/src/cxx_supportlib/vendor-modified/boost/container/static_vector.hpp +46 -1
- data/src/cxx_supportlib/vendor-modified/boost/container/string.hpp +612 -317
- data/src/cxx_supportlib/vendor-modified/boost/container/uses_allocator.hpp +54 -111
- data/src/cxx_supportlib/vendor-modified/boost/container/uses_allocator_construction.hpp +100 -0
- data/src/cxx_supportlib/vendor-modified/boost/container/uses_allocator_fwd.hpp +1 -3
- data/src/cxx_supportlib/vendor-modified/boost/container/vector.hpp +233 -116
- data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash.hpp +5 -1
- data/src/cxx_supportlib/vendor-modified/boost/core/lightweight_test.hpp +17 -10
- data/src/cxx_supportlib/vendor-modified/boost/date_time/period.hpp +1 -3
- data/src/cxx_supportlib/vendor-modified/boost/describe/detail/config.hpp +16 -0
- data/src/cxx_supportlib/vendor-modified/boost/exception/detail/encoder.hpp +114 -0
- data/src/cxx_supportlib/vendor-modified/boost/exception/detail/error_info_impl.hpp +4 -0
- data/src/cxx_supportlib/vendor-modified/boost/exception/detail/requires_cxx11.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/exception/detail/type_info.hpp +211 -1
- data/src/cxx_supportlib/vendor-modified/boost/exception/diagnostic_information.hpp +59 -0
- data/src/cxx_supportlib/vendor-modified/boost/exception/exception.hpp +6 -0
- data/src/cxx_supportlib/vendor-modified/boost/exception/info.hpp +34 -0
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree.hpp +0 -1
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree.hpp +12 -3
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/derivation_value_traits.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/ebo_functor_holder.hpp +29 -174
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/generic_hook.hpp +18 -2
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/key_nodeptr_comp.hpp +0 -1
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/workaround.hpp +4 -5
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/hashtable.hpp +20 -11
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/list.hpp +42 -14
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist.hpp +58 -22
- data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set.hpp +3 -1
- data/src/cxx_supportlib/vendor-modified/boost/iterator/advance.hpp +5 -1
- data/src/cxx_supportlib/vendor-modified/boost/iterator/distance.hpp +8 -2
- data/src/cxx_supportlib/vendor-modified/boost/iterator/is_iterator.hpp +9 -0
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/bad_lexical_cast.hpp +11 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/buffer_view.hpp +9 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/config.hpp +22 -0
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical.hpp +15 -7
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical_streams.hpp +23 -11
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_numeric.hpp +11 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/inf_nan.hpp +9 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/is_character.hpp +11 -2
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_basic_unlockedbuf.hpp +10 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_char_constants.hpp +8 -1
- data/src/cxx_supportlib/vendor-modified/boost/{detail → lexical_cast/detail}/lcast_precision.hpp +13 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_unsigned_converters.hpp +11 -1
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/widest_char.hpp +10 -2
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/try_lexical_convert.hpp +15 -2
- data/src/cxx_supportlib/vendor-modified/boost/lexical_cast.hpp +11 -1
- data/src/cxx_supportlib/vendor-modified/boost/libs/thread/src/pthread/once_atomic.cpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/libs/thread/src/pthread/thread.cpp +48 -46
- data/src/cxx_supportlib/vendor-modified/boost/move/detail/meta_utils.hpp +23 -0
- data/src/cxx_supportlib/vendor-modified/boost/move/detail/move_helpers.hpp +24 -24
- data/src/cxx_supportlib/vendor-modified/boost/move/detail/nsec_clock.hpp +12 -4
- data/src/cxx_supportlib/vendor-modified/boost/move/detail/type_traits.hpp +76 -0
- data/src/cxx_supportlib/vendor-modified/boost/move/detail/workaround.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/move/traits.hpp +11 -0
- data/src/cxx_supportlib/vendor-modified/boost/mp11/algorithm.hpp +58 -37
- data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_copy_if.hpp +1 -2
- data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_map_find.hpp +17 -9
- data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_remove_if.hpp +1 -2
- data/src/cxx_supportlib/vendor-modified/boost/mp11/integer_sequence.hpp +6 -0
- data/src/cxx_supportlib/vendor-modified/boost/mp11/version.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/none_t.hpp +6 -1
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_common_defs.hpp +188 -0
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_factory_support.hpp +0 -6
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_hash.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_nonmember_interface.hpp +117 -0
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_reference_spec.hpp +108 -83
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_relops.hpp +39 -39
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_select_implementation.hpp +37 -0
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_swap.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_trivially_copyable_base.hpp +8 -8
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/union_optional.hpp +724 -0
- data/src/cxx_supportlib/vendor-modified/boost/optional/optional.hpp +93 -220
- data/src/cxx_supportlib/vendor-modified/boost/optional/optional_fwd.hpp +14 -4
- data/src/cxx_supportlib/vendor-modified/boost/optional/optional_io.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/random/binomial_distribution.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/random/uniform_int_distribution.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/rational.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/static_assert.hpp +4 -6
- data/src/cxx_supportlib/vendor-modified/boost/system/api_config.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/system/detail/config.hpp +16 -0
- data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_category.hpp +13 -13
- data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_category_impl.hpp +5 -5
- data/src/cxx_supportlib/vendor-modified/boost/thread/concurrent_queues/detail/sync_deque_base.hpp +3 -2
- data/src/cxx_supportlib/vendor-modified/boost/thread/concurrent_queues/detail/sync_queue_base.hpp +3 -2
- data/src/cxx_supportlib/vendor-modified/boost/thread/detail/thread.hpp +2 -1
- data/src/cxx_supportlib/vendor-modified/boost/thread/experimental/parallel/v2/task_region.hpp +1 -1
- data/src/cxx_supportlib/vendor-modified/boost/thread/future.hpp +30 -28
- data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/once.hpp +6 -3
- data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/once_atomic.hpp +5 -1
- data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/pthread_helpers.hpp +1 -0
- data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/shared_mutex.hpp +16 -16
- data/src/cxx_supportlib/vendor-modified/boost/thread/v2/shared_mutex.hpp +26 -26
- data/src/cxx_supportlib/vendor-modified/boost/unordered/concurrent_flat_map.hpp +196 -6
- data/src/cxx_supportlib/vendor-modified/boost/unordered/concurrent_flat_set.hpp +191 -6
- data/src/cxx_supportlib/vendor-modified/boost/unordered/concurrent_node_map.hpp +196 -5
- data/src/cxx_supportlib/vendor-modified/boost/unordered/concurrent_node_set.hpp +192 -5
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/foa/concurrent_table.hpp +3 -3
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/foa/core.hpp +2 -2
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/foa/table.hpp +3 -3
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/implementation.hpp +52 -16
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/ranges_support.hpp +104 -0
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/type_traits.hpp +1 -14
- data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/unordered_printers.hpp +10 -4
- data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_map.hpp +121 -3
- data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_flat_set.hpp +118 -3
- data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map.hpp +338 -1
- data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_node_map.hpp +121 -3
- data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_node_set.hpp +118 -3
- data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set.hpp +333 -1
- data/src/cxx_supportlib/vendor-modified/boost/version.hpp +2 -2
- data/src/cxx_supportlib/vendor-modified/jsoncpp/json-forwards.h +276 -143
- data/src/cxx_supportlib/vendor-modified/jsoncpp/json.h +1262 -771
- data/src/cxx_supportlib/vendor-modified/jsoncpp/jsoncpp.cpp +1704 -1586
- data/src/nginx_module/ContentHandler.c +35 -0
- data/src/ruby_supportlib/phusion_passenger/common_library.rb +6 -6
- data/src/ruby_supportlib/phusion_passenger/utils/json.rb +25 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller.rb +12 -1
- data/src/ruby_supportlib/phusion_passenger.rb +1 -1
- metadata +73 -8
- data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_utility.hpp +0 -41
- /data/src/cxx_supportlib/{ServerKit/llhttp_http.c → vendor-copy/llhttp/http.c} +0 -0
|
@@ -0,0 +1,2744 @@
|
|
|
1
|
+
//////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// (C) Copyright Ion Gaztanaga 2025-2026. Distributed under the Boost
|
|
4
|
+
// Software License, Version 1.0. (See accompanying file
|
|
5
|
+
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
6
|
+
//
|
|
7
|
+
// See http://www.boost.org/libs/container for documentation.
|
|
8
|
+
//
|
|
9
|
+
//////////////////////////////////////////////////////////////////////////////
|
|
10
|
+
#ifndef BOOST_CONTAINER_DETAIL_DEQUE_IMPL_HPP
|
|
11
|
+
#define BOOST_CONTAINER_DETAIL_DEQUE_IMPL_HPP
|
|
12
|
+
|
|
13
|
+
#ifndef BOOST_CONFIG_HPP
|
|
14
|
+
# include <boost/config.hpp>
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
18
|
+
# pragma once
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#include <boost/container/detail/config_begin.hpp>
|
|
22
|
+
#include <boost/container/detail/workaround.hpp>
|
|
23
|
+
// container
|
|
24
|
+
#include <boost/container/allocator_traits.hpp>
|
|
25
|
+
#include <boost/container/new_allocator.hpp>
|
|
26
|
+
#include <boost/container/container_fwd.hpp>
|
|
27
|
+
#include <boost/container/throw_exception.hpp>
|
|
28
|
+
#include <boost/container/options.hpp>
|
|
29
|
+
// container/detail
|
|
30
|
+
#include <boost/container/detail/advanced_insert_int.hpp>
|
|
31
|
+
#include <boost/container/detail/alloc_helpers.hpp>
|
|
32
|
+
#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
|
|
33
|
+
#include <boost/container/detail/copy_move_algo.hpp>
|
|
34
|
+
#include <boost/container/detail/iterator.hpp>
|
|
35
|
+
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
|
36
|
+
#include <boost/container/detail/iterators.hpp>
|
|
37
|
+
#include <boost/container/detail/min_max.hpp>
|
|
38
|
+
#include <boost/container/detail/mpl.hpp>
|
|
39
|
+
#include <boost/move/detail/to_raw_pointer.hpp>
|
|
40
|
+
#include <boost/container/detail/type_traits.hpp>
|
|
41
|
+
#include <boost/container/detail/math_functions.hpp>
|
|
42
|
+
|
|
43
|
+
// move
|
|
44
|
+
#include <boost/move/adl_move_swap.hpp>
|
|
45
|
+
#include <boost/move/algo/detail/merge.hpp>
|
|
46
|
+
#include <boost/move/iterator.hpp>
|
|
47
|
+
#include <boost/move/traits.hpp>
|
|
48
|
+
#include <boost/move/utility_core.hpp>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// move
|
|
52
|
+
#include <boost/move/adl_move_swap.hpp>
|
|
53
|
+
#include <boost/move/algo/detail/merge.hpp>
|
|
54
|
+
#include <boost/move/iterator.hpp>
|
|
55
|
+
#include <boost/move/traits.hpp>
|
|
56
|
+
#include <boost/move/utility_core.hpp>
|
|
57
|
+
// move/detail
|
|
58
|
+
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
59
|
+
# include <boost/move/detail/fwd_macros.hpp>
|
|
60
|
+
#endif
|
|
61
|
+
#include <boost/move/detail/move_helpers.hpp>
|
|
62
|
+
// other
|
|
63
|
+
#include <boost/assert.hpp>
|
|
64
|
+
// std
|
|
65
|
+
#include <cstddef>
|
|
66
|
+
|
|
67
|
+
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
68
|
+
# include <initializer_list>
|
|
69
|
+
#endif
|
|
70
|
+
|
|
71
|
+
namespace boost {
|
|
72
|
+
namespace container {
|
|
73
|
+
|
|
74
|
+
template <class T>
|
|
75
|
+
struct deque_value_traits
|
|
76
|
+
{
|
|
77
|
+
typedef T value_type;
|
|
78
|
+
BOOST_STATIC_CONSTEXPR bool trivial_dctr = dtl::is_trivially_destructible<value_type>::value;
|
|
79
|
+
BOOST_STATIC_CONSTEXPR bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
template<class T, std::size_t BlockBytes, std::size_t BlockSize, class StoredSizeType>
|
|
83
|
+
struct deque_block_traits
|
|
84
|
+
{
|
|
85
|
+
BOOST_CONTAINER_STATIC_ASSERT_MSG(!(BlockBytes && BlockSize), "BlockBytes and BlockSize can't be specified at the same time");
|
|
86
|
+
//Calculate default block size
|
|
87
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_block_bytes = sizeof(void*)*128u;
|
|
88
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_block_start = (default_block_bytes - 1u)/sizeof(T) + 1u;
|
|
89
|
+
//Round to the next power of two
|
|
90
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_block_size_upp_pow2 = dtl::upper_power_of_2_ct<std::size_t, default_block_start>::value;
|
|
91
|
+
|
|
92
|
+
//Check minimal size
|
|
93
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_min_block_size_pow = 3u;
|
|
94
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_min_block_size = 8u;
|
|
95
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_block_size_initial = default_block_size_upp_pow2 < default_min_block_size
|
|
96
|
+
? default_min_block_size
|
|
97
|
+
: default_block_size_upp_pow2;
|
|
98
|
+
|
|
99
|
+
//Limit by stored size max value
|
|
100
|
+
BOOST_STATIC_CONSTEXPR std::size_t max_stored_size_block_size = std::size_t(1u) << (sizeof(StoredSizeType)*CHAR_BIT - default_min_block_size_pow);
|
|
101
|
+
BOOST_STATIC_CONSTEXPR std::size_t default_block_size = default_block_size_initial > max_stored_size_block_size
|
|
102
|
+
? max_stored_size_block_size
|
|
103
|
+
: default_block_size_initial;
|
|
104
|
+
//Now select between the default or the specified by the user
|
|
105
|
+
BOOST_STATIC_CONSTEXPR std::size_t value = BlockSize ? BlockSize
|
|
106
|
+
: BlockBytes ? (BlockBytes-1u)/sizeof(T) + 1u : default_block_size
|
|
107
|
+
;
|
|
108
|
+
BOOST_CONTAINER_STATIC_ASSERT_MSG(value <= max_stored_size_block_size, "BlockSize or BlockBytes is too big for the stored_size_type");
|
|
109
|
+
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
113
|
+
|
|
114
|
+
////////////////////////////////////////////////////////////////////////////
|
|
115
|
+
//
|
|
116
|
+
// Implementation of deque iterators. This is a random access iterator
|
|
117
|
+
//
|
|
118
|
+
////////////////////////////////////////////////////////////////////////////
|
|
119
|
+
//
|
|
120
|
+
// Class invariants:
|
|
121
|
+
// For any nonsingular iterator i:
|
|
122
|
+
// i.node is the address of an element in the map array. The
|
|
123
|
+
// contents of i.node is a pointer to the beginning of a node.
|
|
124
|
+
// i.cur is a pointer in the range [i.first, i.last). NOTE:
|
|
125
|
+
// the implication of this is that i.cur is always a dereferenceable
|
|
126
|
+
// pointer, even if i is a past-the-end iterator.
|
|
127
|
+
// For every node other than start.node and finish.node, every element
|
|
128
|
+
// in the node is an initialized object. If start.node == finish.node,
|
|
129
|
+
// then [start.cur, finish.cur) are initialized objects, and
|
|
130
|
+
// the elements outside that range are uninitialized storage. Otherwise,
|
|
131
|
+
// [start.cur, start.last) and [finish.first, finish.cur) are initialized
|
|
132
|
+
// objects, and [start.first, start.cur) and [finish.cur, finish.last)
|
|
133
|
+
// are uninitialized storage.
|
|
134
|
+
// [map, map + map_size) is a valid range.
|
|
135
|
+
// [start.node, finish.node] is a valid range contained within
|
|
136
|
+
// [map, map + map_size).
|
|
137
|
+
// A pointer in the range [map, map + map_size) points to an allocated node
|
|
138
|
+
// if and only if the pointer is in the range [start.node, finish.node].
|
|
139
|
+
template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize, class StoredSizeType>
|
|
140
|
+
class deque_iterator
|
|
141
|
+
{
|
|
142
|
+
public:
|
|
143
|
+
typedef std::random_access_iterator_tag iterator_category;
|
|
144
|
+
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
|
145
|
+
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
|
146
|
+
typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
|
|
147
|
+
typedef typename dtl::if_c
|
|
148
|
+
< IsConst
|
|
149
|
+
, typename boost::intrusive::pointer_traits<Pointer>::template
|
|
150
|
+
rebind_pointer<const value_type>::type
|
|
151
|
+
, Pointer
|
|
152
|
+
>::type pointer;
|
|
153
|
+
typedef typename dtl::if_c
|
|
154
|
+
< IsConst
|
|
155
|
+
, const value_type&
|
|
156
|
+
, value_type&
|
|
157
|
+
>::type reference;
|
|
158
|
+
|
|
159
|
+
BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
|
|
160
|
+
{
|
|
161
|
+
return deque_block_traits<value_type, BlockBytes, BlockSize, StoredSizeType>::value;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
|
|
165
|
+
{ return difference_type((get_block_size())); }
|
|
166
|
+
|
|
167
|
+
typedef Pointer val_alloc_ptr;
|
|
168
|
+
typedef typename boost::intrusive::pointer_traits<Pointer>::
|
|
169
|
+
template rebind_pointer<Pointer>::type index_pointer;
|
|
170
|
+
|
|
171
|
+
class nat
|
|
172
|
+
{
|
|
173
|
+
public:
|
|
174
|
+
inline Pointer get_cur() const { return Pointer(); }
|
|
175
|
+
inline index_pointer get_node() const { return index_pointer(); }
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
typedef typename dtl::if_c< IsConst
|
|
179
|
+
, deque_iterator<Pointer, false, BlockBytes, BlockSize, StoredSizeType>
|
|
180
|
+
, nat>::type nonconst_iterator_arg;
|
|
181
|
+
|
|
182
|
+
typedef deque_iterator<Pointer, false, BlockBytes, BlockSize, StoredSizeType> nonconst_iterator;
|
|
183
|
+
|
|
184
|
+
Pointer m_cur;
|
|
185
|
+
index_pointer m_node;
|
|
186
|
+
|
|
187
|
+
public:
|
|
188
|
+
|
|
189
|
+
BOOST_CONTAINER_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_cur() const { return m_cur; }
|
|
190
|
+
BOOST_CONTAINER_NODISCARD BOOST_CONTAINER_FORCEINLINE index_pointer get_node() const { return m_node; }
|
|
191
|
+
BOOST_CONTAINER_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_first() const { return *m_node; }
|
|
192
|
+
BOOST_CONTAINER_NODISCARD BOOST_CONTAINER_FORCEINLINE Pointer get_last() const { return *m_node + get_block_ssize(); }
|
|
193
|
+
|
|
194
|
+
inline deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_NOEXCEPT_OR_NOTHROW
|
|
195
|
+
: m_cur(x), m_node(y)
|
|
196
|
+
{}
|
|
197
|
+
|
|
198
|
+
inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
|
|
199
|
+
: m_cur(), m_node() //Value initialization to achieve "null iterators" (N3644)
|
|
200
|
+
{}
|
|
201
|
+
|
|
202
|
+
inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
203
|
+
: m_cur(x.get_cur()), m_node(x.get_node())
|
|
204
|
+
{}
|
|
205
|
+
|
|
206
|
+
inline deque_iterator(const nonconst_iterator_arg& x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
207
|
+
: m_cur(x.get_cur()), m_node(x.get_node())
|
|
208
|
+
{}
|
|
209
|
+
|
|
210
|
+
inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
211
|
+
{ m_cur = x.get_cur(); m_node = x.get_node(); return *this; }
|
|
212
|
+
|
|
213
|
+
inline deque_iterator& operator=(const nonconst_iterator_arg& x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
214
|
+
{ m_cur = x.get_cur(); m_node = x.get_node(); return *this; }
|
|
215
|
+
|
|
216
|
+
inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
217
|
+
{
|
|
218
|
+
return nonconst_iterator(this->get_cur(), this->get_node());
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
222
|
+
{ return *this->m_cur; }
|
|
223
|
+
|
|
224
|
+
inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
225
|
+
{ return this->m_cur; }
|
|
226
|
+
|
|
227
|
+
BOOST_CONTAINER_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
228
|
+
{
|
|
229
|
+
if(this->m_cur == x.m_cur){ //Includes when both are null
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
|
|
233
|
+
return block_size * (this->m_node - x.m_node) +
|
|
234
|
+
(this->m_cur - this->get_first()) - (x.m_cur - x.get_first());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
|
|
238
|
+
{
|
|
239
|
+
BOOST_ASSERT(!!m_cur);
|
|
240
|
+
++this->m_cur;
|
|
241
|
+
const Pointer last = *m_node + get_block_ssize();
|
|
242
|
+
if (BOOST_UNLIKELY(this->m_cur == last)) {
|
|
243
|
+
++this->m_node;
|
|
244
|
+
this->m_cur = *this->m_node;
|
|
245
|
+
}
|
|
246
|
+
return *this;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
|
|
250
|
+
{
|
|
251
|
+
deque_iterator tmp(*this);
|
|
252
|
+
++*this;
|
|
253
|
+
return tmp;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
//Some GCC versions issue bogus warnings about array bounds here
|
|
257
|
+
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
258
|
+
# pragma GCC diagnostic ignored "-Warray-bounds"
|
|
259
|
+
#endif
|
|
260
|
+
|
|
261
|
+
deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
|
|
262
|
+
{
|
|
263
|
+
BOOST_ASSERT(!!m_cur);
|
|
264
|
+
const Pointer first = *m_node;
|
|
265
|
+
if (BOOST_UNLIKELY(this->m_cur == first)) {
|
|
266
|
+
--this->m_node;
|
|
267
|
+
this->m_cur = *this->m_node;
|
|
268
|
+
BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
|
|
269
|
+
this->m_cur += block_size - 1;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
--this->m_cur;
|
|
273
|
+
}
|
|
274
|
+
return *this;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
278
|
+
#pragma GCC diagnostic pop
|
|
279
|
+
#endif
|
|
280
|
+
|
|
281
|
+
inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
|
|
282
|
+
{
|
|
283
|
+
deque_iterator tmp(*this);
|
|
284
|
+
--*this;
|
|
285
|
+
return tmp;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
289
|
+
{
|
|
290
|
+
if (n){
|
|
291
|
+
BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
|
|
292
|
+
|
|
293
|
+
const difference_type offset = n + (this->m_cur - *this->m_node);
|
|
294
|
+
|
|
295
|
+
if (offset >= 0 && offset < block_size)
|
|
296
|
+
this->m_cur += difference_type(n);
|
|
297
|
+
else {
|
|
298
|
+
const difference_type node_offset =
|
|
299
|
+
offset > 0 ? (offset / block_size)
|
|
300
|
+
: (-difference_type((-offset - 1) / block_size) - 1);
|
|
301
|
+
this->m_node += node_offset;
|
|
302
|
+
this->m_cur = *this->m_node + difference_type(offset - node_offset * block_size);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return *this;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
309
|
+
deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
310
|
+
{ deque_iterator tmp(*this); return tmp += n; }
|
|
311
|
+
|
|
312
|
+
inline
|
|
313
|
+
deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
314
|
+
{ return *this += -n; }
|
|
315
|
+
|
|
316
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
317
|
+
deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
318
|
+
{ deque_iterator tmp(*this); return tmp -= n; }
|
|
319
|
+
|
|
320
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
321
|
+
reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
322
|
+
{
|
|
323
|
+
BOOST_ASSERT(!!m_cur);
|
|
324
|
+
BOOST_CONSTEXPR_OR_CONST difference_type block_size = get_block_ssize();
|
|
325
|
+
|
|
326
|
+
const difference_type offset = n + (this->m_cur - *this->m_node);
|
|
327
|
+
|
|
328
|
+
if (offset >= 0 && offset < block_size)
|
|
329
|
+
return this->m_cur[difference_type(n)];
|
|
330
|
+
else {
|
|
331
|
+
const difference_type node_offset = offset > 0
|
|
332
|
+
? (offset / block_size)
|
|
333
|
+
: (-difference_type((-offset - 1) / block_size) - 1);
|
|
334
|
+
return (this->m_node[node_offset]) [offset - node_offset * block_size];
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
//Comparisons
|
|
339
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
340
|
+
friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
|
341
|
+
{ return l.m_cur == r.m_cur; }
|
|
342
|
+
|
|
343
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
344
|
+
friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
|
345
|
+
{ return l.m_cur != r.m_cur; }
|
|
346
|
+
|
|
347
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
348
|
+
friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
|
349
|
+
{ return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
|
|
350
|
+
|
|
351
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
352
|
+
friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
|
353
|
+
{ return r < l; }
|
|
354
|
+
|
|
355
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
356
|
+
friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
|
357
|
+
{ return !(r < l); }
|
|
358
|
+
|
|
359
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
360
|
+
friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
|
361
|
+
{ return !(l < r); }
|
|
362
|
+
|
|
363
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
364
|
+
friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
365
|
+
{ return x += n; }
|
|
366
|
+
|
|
367
|
+
inline void priv_set_node(index_pointer new_node) BOOST_NOEXCEPT_OR_NOTHROW
|
|
368
|
+
{ this->m_node = new_node; }
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
////////////////////////////////////////////////////////////////////////////
|
|
372
|
+
//
|
|
373
|
+
// Specialization of segmented_iterator_traits
|
|
374
|
+
//
|
|
375
|
+
////////////////////////////////////////////////////////////////////////////
|
|
376
|
+
|
|
377
|
+
template<class Iterator>
|
|
378
|
+
struct segmented_iterator_traits;
|
|
379
|
+
|
|
380
|
+
struct segmented_iterator_tag;
|
|
381
|
+
|
|
382
|
+
template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize, class StoredSizeType>
|
|
383
|
+
struct segmented_iterator_traits< deque_iterator<Pointer, IsConst, BlockBytes, BlockSize, StoredSizeType> >
|
|
384
|
+
{
|
|
385
|
+
typedef segmented_iterator_tag is_segmented_iterator;
|
|
386
|
+
typedef deque_iterator<Pointer, IsConst, BlockBytes, BlockSize, StoredSizeType> iterator;
|
|
387
|
+
|
|
388
|
+
typedef typename iterator::val_alloc_ptr local_iterator;
|
|
389
|
+
typedef typename iterator::index_pointer segment_iterator;
|
|
390
|
+
|
|
391
|
+
BOOST_CONTAINER_FORCEINLINE static segment_iterator segment(iterator it)
|
|
392
|
+
{ return it.get_node(); }
|
|
393
|
+
|
|
394
|
+
BOOST_CONTAINER_FORCEINLINE static local_iterator local(iterator it)
|
|
395
|
+
{ return it.get_cur(); }
|
|
396
|
+
|
|
397
|
+
BOOST_CONTAINER_FORCEINLINE static iterator compose(segment_iterator s, local_iterator l)
|
|
398
|
+
{
|
|
399
|
+
if (BOOST_UNLIKELY(s && l == (end)(s))) {
|
|
400
|
+
++s;
|
|
401
|
+
l = *s;
|
|
402
|
+
}
|
|
403
|
+
return iterator(l, s);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
BOOST_CONTAINER_FORCEINLINE static local_iterator begin(segment_iterator s)
|
|
407
|
+
{
|
|
408
|
+
BOOST_ASSERT(s != segment_iterator());
|
|
409
|
+
return *s;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
BOOST_CONTAINER_FORCEINLINE static local_iterator end(segment_iterator s)
|
|
413
|
+
{
|
|
414
|
+
BOOST_ASSERT(s != segment_iterator());
|
|
415
|
+
return *s + iterator::get_block_size();
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
////////////////////////////////////////////////////////////////////////////
|
|
420
|
+
//
|
|
421
|
+
// get_deque_opt
|
|
422
|
+
//
|
|
423
|
+
////////////////////////////////////////////////////////////////////////////
|
|
424
|
+
|
|
425
|
+
template<class Options, class AllocatorSizeType>
|
|
426
|
+
struct get_deque_opt
|
|
427
|
+
{
|
|
428
|
+
typedef deque_opt< Options::block_bytes, Options::block_size
|
|
429
|
+
, typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
|
|
430
|
+
, Options::reservable> type;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
template<class AllocatorSizeType>
|
|
434
|
+
struct get_deque_opt<void, AllocatorSizeType>
|
|
435
|
+
{
|
|
436
|
+
typedef deque_opt<deque_null_opt::block_bytes, deque_null_opt::block_size, AllocatorSizeType, deque_null_opt::reservable> type;
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
////////////////////////////////////////////////////////////////////////////
|
|
440
|
+
//
|
|
441
|
+
// deque_members_holder
|
|
442
|
+
//
|
|
443
|
+
////////////////////////////////////////////////////////////////////////////
|
|
444
|
+
|
|
445
|
+
// External members holder: holds m_start_off when not single-ended; specialization for single-ended has no start offset member.
|
|
446
|
+
template <class Allocator, class StoredSizeType, bool SingleEnded>
|
|
447
|
+
struct deque_members_holder;
|
|
448
|
+
|
|
449
|
+
template <class Allocator, class StoredSizeType>
|
|
450
|
+
struct deque_members_holder<Allocator, StoredSizeType, false> : Allocator
|
|
451
|
+
{
|
|
452
|
+
typedef typename allocator_traits<Allocator>::pointer pointer;
|
|
453
|
+
typedef typename allocator_traits<Allocator>::size_type size_type;
|
|
454
|
+
typedef typename allocator_traits<Allocator>::template rebind_traits<pointer>::pointer PtrAllocPtr;
|
|
455
|
+
|
|
456
|
+
PtrAllocPtr m_map;
|
|
457
|
+
StoredSizeType m_map_size;
|
|
458
|
+
StoredSizeType m_start_off;
|
|
459
|
+
StoredSizeType m_finish_off;
|
|
460
|
+
|
|
461
|
+
deque_members_holder()
|
|
462
|
+
: Allocator()
|
|
463
|
+
, m_map(), m_map_size()
|
|
464
|
+
, m_start_off(), m_finish_off()
|
|
465
|
+
{}
|
|
466
|
+
|
|
467
|
+
template<class ValAllocConvertible>
|
|
468
|
+
explicit deque_members_holder(BOOST_FWD_REF(ValAllocConvertible) va)
|
|
469
|
+
: Allocator(boost::forward<ValAllocConvertible>(va))
|
|
470
|
+
, m_map(), m_map_size()
|
|
471
|
+
, m_start_off(), m_finish_off()
|
|
472
|
+
{}
|
|
473
|
+
|
|
474
|
+
void swap(deque_members_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
475
|
+
{
|
|
476
|
+
::boost::adl_move_swap(this->m_map, x.m_map);
|
|
477
|
+
::boost::adl_move_swap(this->m_map_size, x.m_map_size);
|
|
478
|
+
::boost::adl_move_swap(this->m_start_off, x.m_start_off);
|
|
479
|
+
::boost::adl_move_swap(this->m_finish_off, x.m_finish_off);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
BOOST_CONTAINER_FORCEINLINE StoredSizeType get_start_off() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
483
|
+
{ return m_start_off; }
|
|
484
|
+
|
|
485
|
+
BOOST_CONTAINER_FORCEINLINE void set_start_off(size_type v) BOOST_NOEXCEPT_OR_NOTHROW
|
|
486
|
+
{ m_start_off = static_cast<StoredSizeType>(v); }
|
|
487
|
+
|
|
488
|
+
BOOST_CONTAINER_FORCEINLINE void inc_start() BOOST_NOEXCEPT_OR_NOTHROW
|
|
489
|
+
{ ++m_start_off; }
|
|
490
|
+
|
|
491
|
+
BOOST_CONTAINER_FORCEINLINE void dec_start() BOOST_NOEXCEPT_OR_NOTHROW
|
|
492
|
+
{ --m_start_off; }
|
|
493
|
+
|
|
494
|
+
BOOST_CONTAINER_FORCEINLINE void inc_start(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
495
|
+
{ m_start_off = static_cast<StoredSizeType>(m_start_off + n); }
|
|
496
|
+
|
|
497
|
+
BOOST_CONTAINER_FORCEINLINE void dec_start(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
498
|
+
{ m_start_off = static_cast<StoredSizeType>(m_start_off - n); }
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
template <class Allocator, class StoredSizeType>
|
|
502
|
+
struct deque_members_holder<Allocator, StoredSizeType, true> : Allocator
|
|
503
|
+
{
|
|
504
|
+
typedef typename allocator_traits<Allocator>::pointer pointer;
|
|
505
|
+
typedef typename allocator_traits<Allocator>::size_type size_type;
|
|
506
|
+
typedef typename allocator_traits<Allocator>::template rebind_traits<pointer>::pointer PtrAllocPtr;
|
|
507
|
+
|
|
508
|
+
PtrAllocPtr m_map;
|
|
509
|
+
StoredSizeType m_map_size;
|
|
510
|
+
StoredSizeType m_finish_off;
|
|
511
|
+
|
|
512
|
+
deque_members_holder()
|
|
513
|
+
: Allocator()
|
|
514
|
+
, m_map(), m_map_size()
|
|
515
|
+
, m_finish_off()
|
|
516
|
+
{}
|
|
517
|
+
|
|
518
|
+
template<class ValAllocConvertible>
|
|
519
|
+
explicit deque_members_holder(BOOST_FWD_REF(ValAllocConvertible) va)
|
|
520
|
+
: Allocator(boost::forward<ValAllocConvertible>(va))
|
|
521
|
+
, m_map(), m_map_size()
|
|
522
|
+
, m_finish_off()
|
|
523
|
+
{}
|
|
524
|
+
|
|
525
|
+
void swap(deque_members_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
526
|
+
{
|
|
527
|
+
::boost::adl_move_swap(this->m_map, x.m_map);
|
|
528
|
+
::boost::adl_move_swap(this->m_map_size, x.m_map_size);
|
|
529
|
+
::boost::adl_move_swap(this->m_finish_off, x.m_finish_off);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
BOOST_CONTAINER_FORCEINLINE StoredSizeType get_start_off() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
533
|
+
{ return 0; }
|
|
534
|
+
|
|
535
|
+
BOOST_CONTAINER_FORCEINLINE void set_start_off(size_type s) BOOST_NOEXCEPT_OR_NOTHROW
|
|
536
|
+
{
|
|
537
|
+
BOOST_ASSERT(s == 0);
|
|
538
|
+
(void)s;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
BOOST_CONTAINER_FORCEINLINE void inc_start() BOOST_NOEXCEPT_OR_NOTHROW
|
|
542
|
+
{}
|
|
543
|
+
|
|
544
|
+
BOOST_CONTAINER_FORCEINLINE void dec_start() BOOST_NOEXCEPT_OR_NOTHROW
|
|
545
|
+
{}
|
|
546
|
+
|
|
547
|
+
BOOST_CONTAINER_FORCEINLINE void inc_start(size_type) BOOST_NOEXCEPT_OR_NOTHROW
|
|
548
|
+
{}
|
|
549
|
+
|
|
550
|
+
BOOST_CONTAINER_FORCEINLINE void dec_start(size_type) BOOST_NOEXCEPT_OR_NOTHROW
|
|
551
|
+
{}
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
////////////////////////////////////////////////////////////////////////////
|
|
555
|
+
//
|
|
556
|
+
// deque_base
|
|
557
|
+
//
|
|
558
|
+
////////////////////////////////////////////////////////////////////////////
|
|
559
|
+
|
|
560
|
+
// Deque base class. It has two purposes. First, its constructor
|
|
561
|
+
// and destructor allocate (but don't initialize) storage. This makes
|
|
562
|
+
// exception safety easier.
|
|
563
|
+
template <class Allocator, class Options, bool SingleEnded>
|
|
564
|
+
class deque_base
|
|
565
|
+
{
|
|
566
|
+
BOOST_COPYABLE_AND_MOVABLE(deque_base)
|
|
567
|
+
public:
|
|
568
|
+
typedef allocator_traits<Allocator> val_alloc_traits_type;
|
|
569
|
+
typedef typename val_alloc_traits_type::value_type val_alloc_val;
|
|
570
|
+
typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
|
|
571
|
+
typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr;
|
|
572
|
+
typedef typename val_alloc_traits_type::reference val_alloc_ref;
|
|
573
|
+
typedef typename val_alloc_traits_type::const_reference val_alloc_cref;
|
|
574
|
+
typedef typename val_alloc_traits_type::difference_type val_alloc_diff;
|
|
575
|
+
typedef typename val_alloc_traits_type::size_type val_alloc_size;
|
|
576
|
+
typedef typename val_alloc_traits_type::template
|
|
577
|
+
portable_rebind_alloc<val_alloc_ptr>::type ptr_alloc_t;
|
|
578
|
+
typedef allocator_traits<ptr_alloc_t> ptr_alloc_traits_type;
|
|
579
|
+
typedef typename ptr_alloc_traits_type::value_type ptr_alloc_val;
|
|
580
|
+
typedef typename ptr_alloc_traits_type::pointer ptr_alloc_ptr;
|
|
581
|
+
typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
|
|
582
|
+
typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
|
|
583
|
+
typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
|
|
584
|
+
typedef Allocator allocator_type;
|
|
585
|
+
typedef allocator_type stored_allocator_type;
|
|
586
|
+
typedef val_alloc_size size_type;
|
|
587
|
+
typedef val_alloc_diff difference_type;
|
|
588
|
+
|
|
589
|
+
private:
|
|
590
|
+
typedef typename get_deque_opt<Options, val_alloc_size>::type options_type;
|
|
591
|
+
|
|
592
|
+
protected:
|
|
593
|
+
typedef typename options_type::stored_size_type stored_size_type;
|
|
594
|
+
typedef deque_iterator< val_alloc_ptr, false
|
|
595
|
+
, options_type::block_bytes
|
|
596
|
+
, options_type::block_size
|
|
597
|
+
, stored_size_type> iterator;
|
|
598
|
+
typedef deque_iterator< val_alloc_ptr, true
|
|
599
|
+
, options_type::block_bytes
|
|
600
|
+
, options_type::block_size
|
|
601
|
+
, stored_size_type> const_iterator;
|
|
602
|
+
|
|
603
|
+
static const bool is_reservable = options_type::reservable;
|
|
604
|
+
|
|
605
|
+
BOOST_CONSTEXPR inline static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
|
|
606
|
+
{ return val_alloc_diff((get_block_size())); }
|
|
607
|
+
|
|
608
|
+
BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
|
|
609
|
+
{ return deque_block_traits<val_alloc_val, options_type::block_bytes, options_type::block_size, stored_size_type>::value; }
|
|
610
|
+
|
|
611
|
+
BOOST_CONSTEXPR inline static size_type get_segment_size() BOOST_NOEXCEPT_OR_NOTHROW
|
|
612
|
+
{ return get_block_size(); }
|
|
613
|
+
|
|
614
|
+
typedef deque_value_traits<val_alloc_val> traits_t;
|
|
615
|
+
|
|
616
|
+
inline val_alloc_ptr prot_allocate_node()
|
|
617
|
+
{
|
|
618
|
+
return this->alloc().allocate(get_block_size());
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
inline void prot_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
|
|
622
|
+
{
|
|
623
|
+
this->alloc().deallocate(p, get_block_size());
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
inline ptr_alloc_ptr prot_allocate_map(size_type n)
|
|
627
|
+
{
|
|
628
|
+
ptr_alloc_t palloc(this->alloc());
|
|
629
|
+
return palloc.allocate(n);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
inline void prot_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
633
|
+
{
|
|
634
|
+
ptr_alloc_t palloc(this->alloc());
|
|
635
|
+
return palloc.deallocate(p, n);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
inline deque_base(size_type num_elements, const allocator_type& a)
|
|
639
|
+
: members_(a)
|
|
640
|
+
{ this->prot_initialize_map_and_nodes(num_elements); }
|
|
641
|
+
|
|
642
|
+
inline explicit deque_base(const allocator_type& a)
|
|
643
|
+
: members_(a)
|
|
644
|
+
{}
|
|
645
|
+
|
|
646
|
+
inline deque_base()
|
|
647
|
+
: members_()
|
|
648
|
+
{}
|
|
649
|
+
|
|
650
|
+
inline explicit deque_base(BOOST_RV_REF(deque_base) x)
|
|
651
|
+
: members_( boost::move(x.alloc()) )
|
|
652
|
+
{}
|
|
653
|
+
|
|
654
|
+
~deque_base()
|
|
655
|
+
{
|
|
656
|
+
if (this->members_.m_map) {
|
|
657
|
+
this->prot_deallocate_all_nodes();
|
|
658
|
+
this->prot_deallocate_map(this->members_.m_map, this->members_.m_map_size);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
private:
|
|
663
|
+
deque_base(const deque_base&);
|
|
664
|
+
|
|
665
|
+
protected:
|
|
666
|
+
|
|
667
|
+
BOOST_STATIC_CONSTEXPR bool is_single_ended = SingleEnded;
|
|
668
|
+
typedef dtl::bool_<is_single_ended> is_single_ended_t;
|
|
669
|
+
|
|
670
|
+
void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
671
|
+
{
|
|
672
|
+
this->members_.swap(x.members_);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
void test_size_against_max(size_type n)
|
|
676
|
+
{
|
|
677
|
+
const size_type max_alloc = val_alloc_traits_type::max_size(this->alloc());
|
|
678
|
+
const size_type max = dtl::limit_by_stored_size_type<size_type, stored_size_type>::clamp(max_alloc);;
|
|
679
|
+
if (BOOST_UNLIKELY(max < n) )
|
|
680
|
+
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
BOOST_CONTAINER_FORCEINLINE void test_size_against_n_nodes(size_type n_nodes)
|
|
684
|
+
{
|
|
685
|
+
test_size_against_max(size_type(size_type(n_nodes * get_block_size()) - 1u));
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
void prot_initialize_map_and_nodes(size_type num_elements)
|
|
689
|
+
{
|
|
690
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
691
|
+
//Even a zero element initialized map+nodes needs at least 1 node (for sentinel finish position)
|
|
692
|
+
size_type num_nodes = size_type(num_elements / block_size + 1u);
|
|
693
|
+
|
|
694
|
+
//Allocate at least one extra slot on each used end to avoid inmediate map reallocation on push/front insertions for non-reservable
|
|
695
|
+
const size_type map_size = dtl::max_value( size_type(InitialMapSize)
|
|
696
|
+
, size_type(num_nodes + size_type(!is_reservable)*(1u + size_type(!is_single_ended))));
|
|
697
|
+
const size_type start_map_pos = is_single_ended ? 0u : size_type(map_size - num_nodes)/2u;
|
|
698
|
+
|
|
699
|
+
//The end position must be representable in stored_size_type
|
|
700
|
+
this->test_size_against_n_nodes(map_size);
|
|
701
|
+
|
|
702
|
+
this->members_.m_map = this->prot_allocate_map(map_size);
|
|
703
|
+
this->members_.m_map_size = static_cast<stored_size_type>(map_size);
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
BOOST_CONTAINER_TRY {
|
|
707
|
+
BOOST_IF_CONSTEXPR(is_reservable){ //reservable implies all slots are allocated with nodes
|
|
708
|
+
this->prot_allocate_nodes(this->members_.m_map, map_size);
|
|
709
|
+
}
|
|
710
|
+
else{ //Otherwise only create the nodes that will hold values
|
|
711
|
+
this->prot_allocate_nodes(this->members_.m_map + difference_type(start_map_pos), num_nodes);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
BOOST_CONTAINER_CATCH(...){
|
|
715
|
+
this->prot_deallocate_map(this->members_.m_map, this->members_.m_map_size);
|
|
716
|
+
this->members_.m_map = ptr_alloc_ptr();
|
|
717
|
+
this->members_.m_map_size = 0;
|
|
718
|
+
BOOST_CONTAINER_RETHROW
|
|
719
|
+
}
|
|
720
|
+
BOOST_CONTAINER_CATCH_END
|
|
721
|
+
|
|
722
|
+
this->members_.set_start_off(static_cast<stored_size_type>(start_map_pos*block_size));
|
|
723
|
+
this->members_.m_finish_off = static_cast<stored_size_type>(members_.get_start_off() + num_elements);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
BOOST_CONTAINER_FORCEINLINE static difference_type priv_new_offset //!single_ended overload
|
|
727
|
+
(dtl::bool_<false>, bool add_at_front, size_type map_size, size_type active_nodes, size_type additional_nodes)
|
|
728
|
+
{
|
|
729
|
+
return difference_type(size_type(map_size - active_nodes) / 2 + (add_at_front ? +additional_nodes : +0));
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
BOOST_CONTAINER_FORCEINLINE static difference_type priv_new_offset //single_ended overload
|
|
733
|
+
(dtl::bool_<true>, bool add_at_front, size_type , size_type , size_type )
|
|
734
|
+
{
|
|
735
|
+
(void)add_at_front;
|
|
736
|
+
BOOST_ASSERT(!add_at_front); //logic_error
|
|
737
|
+
return 0;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
//Single-ended map growth (reservable). The start node is permanently pinned at
|
|
741
|
+
//m_map[0], so the map is never recentered: every node pointer is copied to the
|
|
742
|
+
//front of a larger map and the extra trailing nodes are allocated. Because the
|
|
743
|
+
//node indices are preserved, the start/finish offsets need no fix-up.
|
|
744
|
+
void prot_reallocate_map_and_nodes //is_reservable == true, single_ended == true
|
|
745
|
+
(dtl::bool_<true>, dtl::bool_<true>, const size_type new_elems, const bool add_at_front)
|
|
746
|
+
{
|
|
747
|
+
(void)add_at_front;
|
|
748
|
+
BOOST_ASSERT(!add_at_front); //logic_error: single-ended never grows at front
|
|
749
|
+
const size_type old_map_size = this->members_.m_map_size;
|
|
750
|
+
const ptr_alloc_ptr old_map = this->members_.m_map;
|
|
751
|
+
const size_type additional_nodes = size_type((new_elems - 1u)/get_block_size() + 1u);
|
|
752
|
+
const size_type new_active_nodes = size_type(old_map_size + additional_nodes);
|
|
753
|
+
|
|
754
|
+
//1.5x growth, but at least the needed nodes plus one spare (+1) and the
|
|
755
|
+
//single-ended back-spare (+1), matching the generic sizing.
|
|
756
|
+
const size_type new_map_size =
|
|
757
|
+
dtl::max_value(size_type(old_map_size + old_map_size/2u), size_type(new_active_nodes + 2u));
|
|
758
|
+
|
|
759
|
+
//The end position must be representable in stored_size_type
|
|
760
|
+
this->test_size_against_n_nodes(new_map_size);
|
|
761
|
+
|
|
762
|
+
const ptr_alloc_ptr new_map = this->prot_allocate_map(new_map_size);
|
|
763
|
+
const size_type new_nodes = size_type(new_map_size - old_map_size);
|
|
764
|
+
|
|
765
|
+
BOOST_CONTAINER_TRY {
|
|
766
|
+
this->prot_allocate_nodes(new_map + difference_type(old_map_size), new_nodes);
|
|
767
|
+
}
|
|
768
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
769
|
+
this->prot_deallocate_map(new_map, new_map_size);
|
|
770
|
+
BOOST_CONTAINER_RETHROW
|
|
771
|
+
}
|
|
772
|
+
BOOST_CONTAINER_CATCH_END
|
|
773
|
+
|
|
774
|
+
boost::container::move_n(old_map, old_map_size, new_map);
|
|
775
|
+
this->prot_deallocate_map(old_map, old_map_size);
|
|
776
|
+
|
|
777
|
+
this->members_.m_map = new_map;
|
|
778
|
+
this->members_.m_map_size = static_cast<stored_size_type>(new_map_size);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
//Single-ended map growth (non-reservable). Only the active nodes are allocated;
|
|
782
|
+
//they are copied to the front of a larger map (indices preserved) when the
|
|
783
|
+
//trailing slots are insufficient, then the requested nodes are allocated right
|
|
784
|
+
//after the finish node.
|
|
785
|
+
void prot_reallocate_map_and_nodes //is_reservable == false, single_ended == true
|
|
786
|
+
(dtl::bool_<false>, dtl::bool_<true>, const size_type new_elems, const bool add_at_front)
|
|
787
|
+
{
|
|
788
|
+
(void)add_at_front;
|
|
789
|
+
BOOST_ASSERT(!add_at_front); //logic_error: single-ended never grows at front
|
|
790
|
+
const size_type additional_nodes = size_type((new_elems - 1u)/get_block_size() + 1u);
|
|
791
|
+
const ptr_alloc_ptr old_map = this->members_.m_map;
|
|
792
|
+
const size_type old_map_size = this->members_.m_map_size;
|
|
793
|
+
const ptr_alloc_ptr finish_node = this->prot_finish_node();
|
|
794
|
+
|
|
795
|
+
//start node is m_map[0], so the free slots are all those past the finish node
|
|
796
|
+
const size_type old_active_nodes = size_type(size_type(finish_node - old_map) + 1u);
|
|
797
|
+
const size_type unused_slots = size_type(old_map_size - old_active_nodes);
|
|
798
|
+
|
|
799
|
+
if (additional_nodes > unused_slots) {
|
|
800
|
+
const size_type new_active_nodes = size_type(old_active_nodes + additional_nodes);
|
|
801
|
+
//Doubling size, but at least the needed nodes plus spares (matches generic)
|
|
802
|
+
const size_type new_map_size =
|
|
803
|
+
dtl::max_value(size_type(old_map_size*2u), size_type(new_active_nodes + 2u));
|
|
804
|
+
|
|
805
|
+
//The end position must be representable in stored_size_type
|
|
806
|
+
this->test_size_against_n_nodes(new_map_size);
|
|
807
|
+
|
|
808
|
+
const ptr_alloc_ptr new_map = this->prot_allocate_map(new_map_size);
|
|
809
|
+
//Active nodes keep their indices (start stays at 0), so offsets are unchanged
|
|
810
|
+
boost::container::move_n(old_map, old_active_nodes, new_map);
|
|
811
|
+
this->prot_deallocate_map(old_map, old_map_size);
|
|
812
|
+
|
|
813
|
+
this->members_.m_map = new_map;
|
|
814
|
+
this->members_.m_map_size = static_cast<stored_size_type>(new_map_size);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
this->prot_allocate_nodes(this->prot_finish_node() + 1, additional_nodes);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
void prot_reallocate_map_and_nodes //is_reservable == true, single_ended == false
|
|
821
|
+
(dtl::bool_<true>, dtl::bool_<false>, const size_type new_elems, const bool add_at_front)
|
|
822
|
+
{
|
|
823
|
+
const ptr_alloc_ptr start_node = this->prot_start_node();
|
|
824
|
+
const ptr_alloc_ptr finish_node = this->prot_finish_node();
|
|
825
|
+
const ptr_alloc_ptr next_finish_node = finish_node + 1u;
|
|
826
|
+
const size_type old_active_nodes = size_type(next_finish_node - start_node);
|
|
827
|
+
|
|
828
|
+
const size_type old_map_size = this->members_.m_map_size;
|
|
829
|
+
const ptr_alloc_ptr old_map = this->members_.m_map;
|
|
830
|
+
|
|
831
|
+
const size_type additional_nodes = size_type((new_elems - 1u)/get_block_size() + 1u);
|
|
832
|
+
size_type unused_slots = add_at_front ? size_type(start_node - old_map)
|
|
833
|
+
: size_type(old_map_size - size_type(next_finish_node - old_map));
|
|
834
|
+
|
|
835
|
+
const size_type new_active_nodes = additional_nodes + unused_slots + old_active_nodes;
|
|
836
|
+
//const size_type new_active_nodes = additional_nodes + old_active_nodes;
|
|
837
|
+
ptr_alloc_ptr new_nstart;
|
|
838
|
+
|
|
839
|
+
//Check for 1.5 factor
|
|
840
|
+
if (old_map_size/3u >= new_active_nodes/2u) {
|
|
841
|
+
new_nstart = old_map + priv_new_offset(is_single_ended_t(), add_at_front, old_map_size, new_active_nodes, additional_nodes + unused_slots);
|
|
842
|
+
const ptr_alloc_ptr end_node = start_node + difference_type(old_active_nodes);
|
|
843
|
+
if (new_nstart < start_node)
|
|
844
|
+
boost::movelib::rotate_gcd(new_nstart, start_node, end_node);
|
|
845
|
+
else
|
|
846
|
+
boost::movelib::rotate_gcd(start_node, end_node, new_nstart + old_active_nodes);
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
//1.5 increase, but at least one spare slot on each used end
|
|
850
|
+
const size_type new_map_size =
|
|
851
|
+
dtl::max_value(size_type(old_map_size + old_map_size/2u), size_type(new_active_nodes + 1u + size_type(is_single_ended)));
|
|
852
|
+
|
|
853
|
+
//The end position must be representable in stored_size_type
|
|
854
|
+
this->test_size_against_n_nodes(new_map_size);
|
|
855
|
+
|
|
856
|
+
const ptr_alloc_ptr new_map = this->prot_allocate_map(new_map_size);
|
|
857
|
+
new_nstart = new_map + priv_new_offset(is_single_ended_t(), add_at_front, new_map_size, new_active_nodes, additional_nodes + unused_slots);
|
|
858
|
+
|
|
859
|
+
const size_type new_nodes = size_type(new_map_size - old_map_size);
|
|
860
|
+
|
|
861
|
+
BOOST_CONTAINER_TRY {
|
|
862
|
+
this->prot_allocate_nodes(new_map, new_nodes);
|
|
863
|
+
}
|
|
864
|
+
BOOST_CONTAINER_CATCH(...){
|
|
865
|
+
this->prot_deallocate_map(new_map, new_map_size);
|
|
866
|
+
BOOST_CONTAINER_RETHROW
|
|
867
|
+
}
|
|
868
|
+
BOOST_CONTAINER_CATCH_END
|
|
869
|
+
|
|
870
|
+
const ptr_alloc_ptr new_old_node_limit = new_map + difference_type(new_nodes);
|
|
871
|
+
|
|
872
|
+
//Move old nodes from the old map, rotate to the right position and deallocate the old map
|
|
873
|
+
boost::container::move_n(old_map, old_map_size, new_old_node_limit);
|
|
874
|
+
|
|
875
|
+
const size_type old_active_off = size_type(start_node - old_map);
|
|
876
|
+
const ptr_alloc_ptr active_start = new_old_node_limit + difference_type(old_active_off);
|
|
877
|
+
const ptr_alloc_ptr active_end = active_start + difference_type(old_active_nodes);
|
|
878
|
+
if (new_nstart < active_start)
|
|
879
|
+
boost::movelib::rotate_gcd(new_nstart, active_start, active_end);
|
|
880
|
+
else
|
|
881
|
+
boost::movelib::rotate_gcd(active_start, active_end, new_nstart + difference_type(old_active_nodes));
|
|
882
|
+
|
|
883
|
+
this->prot_deallocate_map(old_map, old_map_size);
|
|
884
|
+
|
|
885
|
+
this->members_.m_map = new_map;
|
|
886
|
+
this->members_.m_map_size = static_cast<stored_size_type>(new_map_size);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
this->prot_start_update_node(new_nstart);
|
|
890
|
+
this->prot_finish_update_node(new_nstart + difference_type(old_active_nodes - 1u));
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
void prot_reallocate_map_and_nodes //is_reservable == false, single_ended == false
|
|
894
|
+
(dtl::bool_<false>, dtl::bool_<false>, const size_type new_elems, const bool add_at_front)
|
|
895
|
+
{
|
|
896
|
+
const size_type additional_nodes = size_type((new_elems - 1u)/get_block_size() + 1u);
|
|
897
|
+
|
|
898
|
+
const ptr_alloc_ptr start_node = this->prot_start_node();
|
|
899
|
+
const ptr_alloc_ptr finish_node = this->prot_finish_node();
|
|
900
|
+
|
|
901
|
+
const size_type old_map_size = this->members_.m_map_size;
|
|
902
|
+
const ptr_alloc_ptr old_map = this->members_.m_map;
|
|
903
|
+
|
|
904
|
+
size_type unused_slots = add_at_front ? size_type(start_node - old_map)
|
|
905
|
+
: size_type(old_map_size - 1u - size_type(finish_node - old_map));
|
|
906
|
+
if (additional_nodes > unused_slots){
|
|
907
|
+
const ptr_alloc_ptr next_finish_node = finish_node + 1u;
|
|
908
|
+
const size_type old_active_nodes = size_type(next_finish_node - start_node);
|
|
909
|
+
const size_type new_active_nodes = size_type(old_active_nodes + additional_nodes);
|
|
910
|
+
|
|
911
|
+
ptr_alloc_ptr new_nstart;
|
|
912
|
+
|
|
913
|
+
if (old_map_size/2u >= new_active_nodes) {
|
|
914
|
+
new_nstart = old_map + priv_new_offset(is_single_ended_t(), add_at_front, old_map_size, new_active_nodes, additional_nodes);
|
|
915
|
+
if (new_nstart < start_node)
|
|
916
|
+
boost::container::move_n(start_node, old_active_nodes, new_nstart);
|
|
917
|
+
else
|
|
918
|
+
boost::container::move_backward_n(next_finish_node, old_active_nodes, new_nstart + difference_type(old_active_nodes));
|
|
919
|
+
}
|
|
920
|
+
else {
|
|
921
|
+
//Doubling size, but at least one spare slot on each end
|
|
922
|
+
const size_type new_map_size = dtl::max_value(size_type(old_map_size*2), size_type(new_active_nodes + 1u + size_type(is_single_ended)));
|
|
923
|
+
|
|
924
|
+
//The end position must be representable in stored_size_type
|
|
925
|
+
this->test_size_against_n_nodes(new_map_size);
|
|
926
|
+
|
|
927
|
+
const ptr_alloc_ptr new_map = this->prot_allocate_map(new_map_size);
|
|
928
|
+
|
|
929
|
+
new_nstart = new_map + priv_new_offset(is_single_ended_t(), add_at_front, new_map_size, new_active_nodes, additional_nodes);
|
|
930
|
+
boost::container::move_n(start_node, old_active_nodes, new_nstart);
|
|
931
|
+
|
|
932
|
+
this->prot_deallocate_map(old_map, old_map_size);
|
|
933
|
+
|
|
934
|
+
this->members_.m_map = new_map;
|
|
935
|
+
this->members_.m_map_size = static_cast<stored_size_type>(new_map_size);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
this->prot_start_update_node(new_nstart);
|
|
939
|
+
this->prot_finish_update_node(new_nstart + difference_type(old_active_nodes - 1u));
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
if(add_at_front)
|
|
943
|
+
this->prot_allocate_nodes(this->prot_start_node() - difference_type(additional_nodes), additional_nodes);
|
|
944
|
+
else
|
|
945
|
+
this->prot_allocate_nodes(this->prot_finish_node() + 1, additional_nodes);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
void prot_allocate_nodes(ptr_alloc_ptr start, size_type n)
|
|
949
|
+
{
|
|
950
|
+
size_type i = 0;
|
|
951
|
+
BOOST_CONTAINER_TRY {
|
|
952
|
+
for (; i < n; ++i)
|
|
953
|
+
start[difference_type(i)] = this->prot_allocate_node();
|
|
954
|
+
}
|
|
955
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
956
|
+
for (size_type j = 0; j < i; ++j)
|
|
957
|
+
this->prot_deallocate_node(start[difference_type(j)]);
|
|
958
|
+
BOOST_CONTAINER_RETHROW
|
|
959
|
+
}
|
|
960
|
+
BOOST_CONTAINER_CATCH_END
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
void prot_deallocate_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
|
|
965
|
+
{
|
|
966
|
+
for (ptr_alloc_ptr n = nstart; n < nfinish; ++n){
|
|
967
|
+
this->prot_deallocate_node(*n);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
void prot_deallocate_nodes_if_not_reservable(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
|
|
972
|
+
{
|
|
973
|
+
(void)nstart; (void)nfinish;
|
|
974
|
+
BOOST_IF_CONSTEXPR(!is_reservable)
|
|
975
|
+
this->prot_deallocate_nodes(nstart, nfinish);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
void prot_deallocate_node_if_not_reservable(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
|
|
979
|
+
{
|
|
980
|
+
(void)p;
|
|
981
|
+
BOOST_IF_CONSTEXPR(!is_reservable)
|
|
982
|
+
this->prot_deallocate_node(p);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
void prot_deallocate_all_nodes()
|
|
986
|
+
{
|
|
987
|
+
BOOST_IF_CONSTEXPR(is_reservable)
|
|
988
|
+
this->prot_deallocate_nodes(this->members_.m_map, this->members_.m_map + difference_type(this->members_.m_map_size));
|
|
989
|
+
else
|
|
990
|
+
this->prot_deallocate_nodes(this->prot_start_node(), this->prot_finish_node() + 1);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
void prot_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
|
|
995
|
+
{
|
|
996
|
+
if (this->members_.m_map) {
|
|
997
|
+
this->prot_deallocate_all_nodes();
|
|
998
|
+
this->prot_deallocate_map(this->members_.m_map, this->members_.m_map_size);
|
|
999
|
+
this->members_.m_map = ptr_alloc_ptr();
|
|
1000
|
+
this->members_.m_map_size = 0u;
|
|
1001
|
+
this->members_.set_start_off(0u);
|
|
1002
|
+
this->members_.m_finish_off = 0u;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
enum { InitialMapSize = 4 };
|
|
1007
|
+
|
|
1008
|
+
protected:
|
|
1009
|
+
typedef deque_members_holder<allocator_type, stored_size_type, is_single_ended> members_holder;
|
|
1010
|
+
members_holder members_;
|
|
1011
|
+
|
|
1012
|
+
inline allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1013
|
+
{ return members_; }
|
|
1014
|
+
|
|
1015
|
+
inline const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1016
|
+
{ return members_; }
|
|
1017
|
+
|
|
1018
|
+
static BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_node_last(ptr_alloc_ptr idx)
|
|
1019
|
+
{
|
|
1020
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1021
|
+
return *idx + difference_type(block_size - 1u);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
BOOST_CONTAINER_FORCEINLINE size_type prot_front_free_capacity() const
|
|
1025
|
+
{
|
|
1026
|
+
BOOST_ASSERT(!is_single_ended);
|
|
1027
|
+
BOOST_IF_CONSTEXPR(is_reservable){
|
|
1028
|
+
return static_cast<size_type>(this->members_.get_start_off());
|
|
1029
|
+
}
|
|
1030
|
+
else{
|
|
1031
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1032
|
+
return static_cast<size_type>(this->members_.get_start_off() % block_size);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
BOOST_CONTAINER_FORCEINLINE size_type prot_back_free_capacity() const
|
|
1037
|
+
{
|
|
1038
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1039
|
+
|
|
1040
|
+
BOOST_IF_CONSTEXPR(is_reservable){
|
|
1041
|
+
return static_cast<size_type>
|
|
1042
|
+
(size_type(this->members_.m_map_size*block_size) - size_type(this->members_.m_map != ptr_alloc_ptr()) - this->members_.m_finish_off);
|
|
1043
|
+
}
|
|
1044
|
+
else {
|
|
1045
|
+
//m_finish_off points to positions [0....block_size-1], and one position is always needed as the sentinel node resulting [block_size-1....0] capacity
|
|
1046
|
+
return static_cast<size_type>(this->members_.m_map ? (block_size - 1u) - (this->members_.m_finish_off % block_size) : 0u);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
//////////////////////////
|
|
1051
|
+
// it_to_off / off_to_it
|
|
1052
|
+
//////////////////////////
|
|
1053
|
+
|
|
1054
|
+
BOOST_CONTAINER_FORCEINLINE stored_size_type prot_it_to_off(const_iterator it) const
|
|
1055
|
+
{
|
|
1056
|
+
const ptr_alloc_ptr n = it.get_node();
|
|
1057
|
+
BOOST_ASSERT(!this->members_.m_map == !n); //Both should be null or both non-null
|
|
1058
|
+
if (BOOST_LIKELY(n != 0)) {
|
|
1059
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1060
|
+
return static_cast<stored_size_type>(std::size_t(n - this->members_.m_map)*block_size + std::size_t(it.get_cur() - *n));
|
|
1061
|
+
}
|
|
1062
|
+
else{
|
|
1063
|
+
return 0;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
BOOST_CONTAINER_FORCEINLINE iterator prot_off_to_it(std::size_t off) const
|
|
1068
|
+
{
|
|
1069
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1070
|
+
const ptr_alloc_ptr node = this->members_.m_map + difference_type(off/block_size);
|
|
1071
|
+
return iterator(node ? *node + difference_type(off%block_size) : val_alloc_ptr(), node);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
stored_size_type prot_it_to_start_off(const_iterator it) const
|
|
1075
|
+
{
|
|
1076
|
+
const size_type off = this->prot_it_to_off(it);
|
|
1077
|
+
BOOST_ASSERT(off >= this->members_.get_start_off());
|
|
1078
|
+
return static_cast<stored_size_type>(off - this->members_.get_start_off());
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/////////////
|
|
1082
|
+
// xxx_to_node
|
|
1083
|
+
/////////////
|
|
1084
|
+
|
|
1085
|
+
BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr prot_off_to_node(std::size_t off) const
|
|
1086
|
+
{
|
|
1087
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1088
|
+
return this->members_.m_map + difference_type(off/block_size);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr prot_start_node() const
|
|
1092
|
+
{
|
|
1093
|
+
return this->prot_off_to_node(this->members_.get_start_off());
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
BOOST_CONTAINER_FORCEINLINE ptr_alloc_ptr prot_finish_node() const
|
|
1097
|
+
{
|
|
1098
|
+
return this->prot_off_to_node(this->members_.m_finish_off);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
//
|
|
1102
|
+
// xxx_to_cur_unchecked versions, faster but need non-default constructed deque
|
|
1103
|
+
//
|
|
1104
|
+
BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_off_to_cur_unchecked(std::size_t off) const
|
|
1105
|
+
{
|
|
1106
|
+
BOOST_ASSERT(!!this->members_.m_map);
|
|
1107
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1108
|
+
const ptr_alloc_ptr node = this->members_.m_map + difference_type(off/block_size);
|
|
1109
|
+
return *node + difference_type(off%block_size);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_start_cur_unchecked() const
|
|
1113
|
+
{
|
|
1114
|
+
return this->prot_off_to_cur_unchecked(this->members_.get_start_off());
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_finish_cur_unchecked() const
|
|
1118
|
+
{
|
|
1119
|
+
return this->prot_off_to_cur_unchecked(this->members_.m_finish_off);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
BOOST_CONTAINER_FORCEINLINE val_alloc_ptr prot_last_cur_unchecked() const
|
|
1123
|
+
{
|
|
1124
|
+
BOOST_ASSERT(members_.get_start_off() != members_.m_finish_off);
|
|
1125
|
+
return this->prot_off_to_cur_unchecked(this->members_.m_finish_off-1u);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
//
|
|
1129
|
+
// functions returning iterators to different positions
|
|
1130
|
+
//
|
|
1131
|
+
BOOST_CONTAINER_FORCEINLINE const_iterator prot_start() const
|
|
1132
|
+
{ return this->prot_off_to_it(members_.get_start_off()); }
|
|
1133
|
+
|
|
1134
|
+
BOOST_CONTAINER_FORCEINLINE iterator prot_start()
|
|
1135
|
+
{ return this->prot_off_to_it(members_.get_start_off()); }
|
|
1136
|
+
|
|
1137
|
+
BOOST_CONTAINER_FORCEINLINE const_iterator prot_finish() const
|
|
1138
|
+
{ return this->prot_off_to_it(members_.m_finish_off); }
|
|
1139
|
+
|
|
1140
|
+
BOOST_CONTAINER_FORCEINLINE iterator prot_finish()
|
|
1141
|
+
{ return this->prot_off_to_it(members_.m_finish_off); }
|
|
1142
|
+
|
|
1143
|
+
BOOST_CONTAINER_FORCEINLINE const_iterator prot_nth(size_type n) const
|
|
1144
|
+
{ return this->prot_off_to_it(size_type(members_.get_start_off() + n)); }
|
|
1145
|
+
|
|
1146
|
+
BOOST_CONTAINER_FORCEINLINE iterator prot_nth(size_type n)
|
|
1147
|
+
{ return this->prot_off_to_it(size_type(members_.get_start_off() + n)); }
|
|
1148
|
+
|
|
1149
|
+
BOOST_CONTAINER_FORCEINLINE iterator prot_back_it()
|
|
1150
|
+
{
|
|
1151
|
+
BOOST_ASSERT(members_.get_start_off() != members_.m_finish_off);
|
|
1152
|
+
return this->prot_off_to_it(size_type(members_.m_finish_off - 1u));
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
//
|
|
1156
|
+
// size/empty
|
|
1157
|
+
//
|
|
1158
|
+
BOOST_CONTAINER_FORCEINLINE size_type prot_size() const
|
|
1159
|
+
{ return size_type(this->members_.m_finish_off - this->members_.get_start_off()); }
|
|
1160
|
+
|
|
1161
|
+
BOOST_CONTAINER_FORCEINLINE bool prot_empty() const
|
|
1162
|
+
{ return this->members_.m_finish_off == this->members_.get_start_off(); }
|
|
1163
|
+
|
|
1164
|
+
//
|
|
1165
|
+
// Functions to move start/finish indexes
|
|
1166
|
+
//
|
|
1167
|
+
BOOST_CONTAINER_FORCEINLINE void prot_inc_finish()
|
|
1168
|
+
{ ++this->members_.m_finish_off; }
|
|
1169
|
+
|
|
1170
|
+
BOOST_CONTAINER_FORCEINLINE void prot_dec_finish()
|
|
1171
|
+
{ --this->members_.m_finish_off; }
|
|
1172
|
+
|
|
1173
|
+
BOOST_CONTAINER_FORCEINLINE void prot_dec_finish(std::size_t n)
|
|
1174
|
+
{ this->members_.m_finish_off = static_cast<stored_size_type>(this->members_.m_finish_off - n); }
|
|
1175
|
+
|
|
1176
|
+
BOOST_CONTAINER_FORCEINLINE void prot_inc_finish(std::size_t n)
|
|
1177
|
+
{ this->members_.m_finish_off = static_cast<stored_size_type>(this->members_.m_finish_off + n); }
|
|
1178
|
+
|
|
1179
|
+
//
|
|
1180
|
+
// Functions to obtain indexes from nodes
|
|
1181
|
+
//
|
|
1182
|
+
BOOST_CONTAINER_FORCEINLINE stored_size_type prot_non_null_node_to_off(ptr_alloc_ptr n) const
|
|
1183
|
+
{
|
|
1184
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1185
|
+
return static_cast<stored_size_type>(std::size_t(n - this->members_.m_map)*block_size);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
inline void prot_start_update_node(ptr_alloc_ptr new_start)
|
|
1189
|
+
{
|
|
1190
|
+
//iG: to-do: optimizable avoiding some division/remainder
|
|
1191
|
+
std::size_t new_block_off = prot_non_null_node_to_off(new_start);
|
|
1192
|
+
this->members_.set_start_off(static_cast<stored_size_type>(new_block_off + (members_.get_start_off() % get_block_size())));
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
inline void prot_finish_update_node(ptr_alloc_ptr new_finish)
|
|
1196
|
+
{
|
|
1197
|
+
//iG: to-do: optimizable avoiding some division/remainder
|
|
1198
|
+
std::size_t new_block_off = prot_non_null_node_to_off(new_finish);
|
|
1199
|
+
this->members_.m_finish_off = static_cast<stored_size_type>(new_block_off + (this->members_.m_finish_off % get_block_size()));
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
inline void prot_reset_finish_to_start()
|
|
1203
|
+
{ this->members_.m_finish_off = members_.get_start_off(); }
|
|
1204
|
+
|
|
1205
|
+
inline void prot_reset_start_to_finish()
|
|
1206
|
+
{ this->members_.set_start_off(this->members_.m_finish_off); }
|
|
1207
|
+
|
|
1208
|
+
inline val_alloc_val *prot_push_back_simple_pos() const
|
|
1209
|
+
{
|
|
1210
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1211
|
+
const std::size_t last_in_block = block_size - 1u;
|
|
1212
|
+
const ptr_alloc_val *const map = boost::movelib::to_raw_pointer(this->members_.m_map);
|
|
1213
|
+
if(BOOST_LIKELY(map != 0)) {
|
|
1214
|
+
const std::size_t off = this->members_.m_finish_off;
|
|
1215
|
+
const std::size_t rem = off % block_size;
|
|
1216
|
+
if(BOOST_LIKELY(rem != last_in_block)){
|
|
1217
|
+
return boost::movelib::to_raw_pointer(map[difference_type(off/block_size)]) + difference_type(rem);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return 0;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
inline val_alloc_val *prot_push_front_simple_pos() const
|
|
1224
|
+
{
|
|
1225
|
+
BOOST_CONSTEXPR_OR_CONST std::size_t block_size = deque_base::get_block_size();
|
|
1226
|
+
//No need to check !m_map, as m_start_off is zero in that case
|
|
1227
|
+
const std::size_t off = members_.get_start_off();
|
|
1228
|
+
const std::size_t rem = off % block_size;
|
|
1229
|
+
if(BOOST_LIKELY(rem != 0u)){
|
|
1230
|
+
return boost::movelib::to_raw_pointer(this->members_.m_map[difference_type(off/block_size)]) + difference_type(rem-1u);
|
|
1231
|
+
}
|
|
1232
|
+
return 0;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
BOOST_CONTAINER_FORCEINLINE bool prot_pop_back_simple_available() const
|
|
1236
|
+
{
|
|
1237
|
+
return (this->members_.m_finish_off % get_block_size()) != 0u;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
BOOST_CONTAINER_FORCEINLINE bool prot_pop_front_simple_available() const
|
|
1241
|
+
{
|
|
1242
|
+
return size_type(members_.get_start_off() % get_block_size()) != size_type(get_block_size() - 1u);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
////////////////////////////////////////////////////////////////////////////
|
|
1248
|
+
//
|
|
1249
|
+
// deque_impl
|
|
1250
|
+
//
|
|
1251
|
+
////////////////////////////////////////////////////////////////////////////
|
|
1252
|
+
|
|
1253
|
+
template <class T, class Allocator, bool SingleEnded, class Options>
|
|
1254
|
+
class deque_impl : protected deque_base<typename real_allocator<T, Allocator>::type, typename get_deque_opt<Options, typename allocator_traits<typename real_allocator<T, Allocator>::type>::size_type>::type, SingleEnded>
|
|
1255
|
+
{
|
|
1256
|
+
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
1257
|
+
private:
|
|
1258
|
+
typedef deque_base<typename real_allocator<T, Allocator>::type, typename get_deque_opt<Options, typename allocator_traits<typename real_allocator<T, Allocator>::type>::size_type>::type, SingleEnded> Base;
|
|
1259
|
+
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
1260
|
+
typedef typename real_allocator<T, Allocator>::type ValAllocator;
|
|
1261
|
+
typedef constant_iterator<T> c_it;
|
|
1262
|
+
|
|
1263
|
+
public:
|
|
1264
|
+
|
|
1265
|
+
//////////////////////////////////////////////
|
|
1266
|
+
//
|
|
1267
|
+
// types
|
|
1268
|
+
//
|
|
1269
|
+
//////////////////////////////////////////////
|
|
1270
|
+
|
|
1271
|
+
typedef T value_type;
|
|
1272
|
+
typedef ValAllocator allocator_type;
|
|
1273
|
+
typedef typename ::boost::container::allocator_traits<ValAllocator>::pointer pointer;
|
|
1274
|
+
typedef typename ::boost::container::allocator_traits<ValAllocator>::const_pointer const_pointer;
|
|
1275
|
+
typedef typename ::boost::container::allocator_traits<ValAllocator>::reference reference;
|
|
1276
|
+
typedef typename ::boost::container::allocator_traits<ValAllocator>::const_reference const_reference;
|
|
1277
|
+
typedef typename ::boost::container::allocator_traits<ValAllocator>::size_type size_type;
|
|
1278
|
+
typedef typename ::boost::container::allocator_traits<ValAllocator>::difference_type difference_type;
|
|
1279
|
+
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
|
|
1280
|
+
typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
|
|
1281
|
+
typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
|
|
1282
|
+
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
|
|
1283
|
+
typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
|
|
1284
|
+
|
|
1285
|
+
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
1286
|
+
|
|
1287
|
+
private: // Internal typedefs
|
|
1288
|
+
|
|
1289
|
+
//`allocator_type::value_type` must match container's `value type`. If this
|
|
1290
|
+
//assertion fails, please review your allocator definition.
|
|
1291
|
+
BOOST_CONTAINER_STATIC_ASSERT((dtl::is_same<value_type, typename allocator_traits<ValAllocator>::value_type>::value));
|
|
1292
|
+
|
|
1293
|
+
BOOST_COPYABLE_AND_MOVABLE(deque_impl)
|
|
1294
|
+
typedef typename Base::ptr_alloc_ptr index_pointer;
|
|
1295
|
+
typedef allocator_traits<ValAllocator> allocator_traits_type;
|
|
1296
|
+
typedef typename Base::stored_size_type stored_size_type;
|
|
1297
|
+
|
|
1298
|
+
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
1299
|
+
|
|
1300
|
+
using Base::get_block_ssize;
|
|
1301
|
+
using Base::is_single_ended;
|
|
1302
|
+
|
|
1303
|
+
public:
|
|
1304
|
+
|
|
1305
|
+
using Base::get_block_size;
|
|
1306
|
+
using Base::get_segment_size;
|
|
1307
|
+
|
|
1308
|
+
static const std::size_t is_reservable = Base::is_reservable;
|
|
1309
|
+
|
|
1310
|
+
//////////////////////////////////////////////
|
|
1311
|
+
//
|
|
1312
|
+
// construct/copy/destroy
|
|
1313
|
+
//
|
|
1314
|
+
//////////////////////////////////////////////
|
|
1315
|
+
|
|
1316
|
+
inline deque_impl()
|
|
1317
|
+
BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValAllocator>::value)
|
|
1318
|
+
: Base()
|
|
1319
|
+
{}
|
|
1320
|
+
|
|
1321
|
+
inline explicit deque_impl(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
|
|
1322
|
+
: Base(a)
|
|
1323
|
+
{}
|
|
1324
|
+
|
|
1325
|
+
inline explicit deque_impl(size_type n)
|
|
1326
|
+
: Base(n, allocator_type())
|
|
1327
|
+
{
|
|
1328
|
+
dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
|
|
1329
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
|
|
1330
|
+
//deque_base will deallocate in case of exception...
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
inline deque_impl(size_type n, default_init_t)
|
|
1334
|
+
: Base(n, allocator_type())
|
|
1335
|
+
{
|
|
1336
|
+
dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
|
|
1337
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
|
|
1338
|
+
//deque_base will deallocate in case of exception...
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
inline explicit deque_impl(size_type n, const allocator_type &a)
|
|
1342
|
+
: Base(n, a)
|
|
1343
|
+
{
|
|
1344
|
+
dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
|
|
1345
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
|
|
1346
|
+
//deque_base will deallocate in case of exception...
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
inline deque_impl(size_type n, default_init_t, const allocator_type &a)
|
|
1350
|
+
: Base(n, a)
|
|
1351
|
+
{
|
|
1352
|
+
dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
|
|
1353
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
|
|
1354
|
+
//deque_base will deallocate in case of exception...
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
inline deque_impl(size_type n, const value_type& value)
|
|
1358
|
+
: Base(n, allocator_type())
|
|
1359
|
+
{ this->priv_fill_initialize(n, value); }
|
|
1360
|
+
|
|
1361
|
+
inline deque_impl(size_type n, const value_type& value, const allocator_type& a)
|
|
1362
|
+
: Base(n, a)
|
|
1363
|
+
{ this->priv_fill_initialize(n, value); }
|
|
1364
|
+
|
|
1365
|
+
template <class InIt>
|
|
1366
|
+
inline deque_impl(InIt first, InIt last
|
|
1367
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1368
|
+
, typename dtl::disable_if_convertible
|
|
1369
|
+
<InIt, size_type>::type * = 0
|
|
1370
|
+
#endif
|
|
1371
|
+
)
|
|
1372
|
+
: Base(allocator_type())
|
|
1373
|
+
{
|
|
1374
|
+
this->priv_range_initialize(first, last);
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
template <class InIt>
|
|
1378
|
+
inline deque_impl(InIt first, InIt last, const allocator_type& a
|
|
1379
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1380
|
+
, typename dtl::disable_if_convertible
|
|
1381
|
+
<InIt, size_type>::type * = 0
|
|
1382
|
+
#endif
|
|
1383
|
+
)
|
|
1384
|
+
: Base(a)
|
|
1385
|
+
{
|
|
1386
|
+
this->priv_range_initialize(first, last);
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
1390
|
+
inline deque_impl(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
|
|
1391
|
+
: Base(a)
|
|
1392
|
+
{
|
|
1393
|
+
this->priv_range_initialize(il.begin(), il.end());
|
|
1394
|
+
}
|
|
1395
|
+
#endif
|
|
1396
|
+
|
|
1397
|
+
inline deque_impl(const deque_impl& x)
|
|
1398
|
+
: Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
|
|
1399
|
+
{
|
|
1400
|
+
if(x.size()){
|
|
1401
|
+
this->prot_initialize_map_and_nodes(x.size());
|
|
1402
|
+
this->priv_segmented_uninitialized_copy_alloc_n(x.begin(), x.size(), this->begin());
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
inline deque_impl(BOOST_RV_REF(deque_impl) x) BOOST_NOEXCEPT_OR_NOTHROW
|
|
1407
|
+
: Base(BOOST_MOVE_BASE(Base, x))
|
|
1408
|
+
{ this->swap_members(x); }
|
|
1409
|
+
|
|
1410
|
+
deque_impl(const deque_impl& x, const BOOST_CONTAINER_DOC1ST(allocator_type, typename dtl::type_identity<allocator_type>::type) &a)
|
|
1411
|
+
: Base(a)
|
|
1412
|
+
{
|
|
1413
|
+
if(x.size()){
|
|
1414
|
+
this->prot_initialize_map_and_nodes(x.size());
|
|
1415
|
+
this->priv_segmented_uninitialized_copy_alloc_n(x.begin(), x.size(), this->begin());
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
deque_impl(BOOST_RV_REF(deque_impl) x, const BOOST_CONTAINER_DOC1ST(allocator_type, typename dtl::type_identity<allocator_type>::type) &a)
|
|
1420
|
+
: Base(a)
|
|
1421
|
+
{
|
|
1422
|
+
if(x.alloc() == a){
|
|
1423
|
+
this->swap_members(x);
|
|
1424
|
+
}
|
|
1425
|
+
else{
|
|
1426
|
+
if(x.size()){
|
|
1427
|
+
this->prot_initialize_map_and_nodes(x.size());
|
|
1428
|
+
this->priv_segmented_uninitialized_move_alloc_n(x.begin(), x.size(), this->begin());
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
inline ~deque_impl() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1434
|
+
{
|
|
1435
|
+
this->prot_destroy_range(this->prot_start(), this->prot_finish());
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
deque_impl& operator= (BOOST_COPY_ASSIGN_REF(deque_impl) x)
|
|
1439
|
+
{
|
|
1440
|
+
if (BOOST_LIKELY(&x != this)){
|
|
1441
|
+
allocator_type &this_alloc = this->alloc();
|
|
1442
|
+
const allocator_type &x_alloc = x.alloc();
|
|
1443
|
+
dtl::bool_<allocator_traits_type::
|
|
1444
|
+
propagate_on_container_copy_assignment::value> flag;
|
|
1445
|
+
if(flag && this_alloc != x_alloc){
|
|
1446
|
+
this->clear();
|
|
1447
|
+
this->shrink_to_fit();
|
|
1448
|
+
}
|
|
1449
|
+
dtl::assign_alloc(this->alloc(), x.alloc(), flag);
|
|
1450
|
+
this->assign(x.cbegin(), x.cend());
|
|
1451
|
+
}
|
|
1452
|
+
return *this;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
deque_impl& operator= (BOOST_RV_REF(deque_impl) x)
|
|
1456
|
+
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
|
|
1457
|
+
|| allocator_traits_type::is_always_equal::value)
|
|
1458
|
+
{
|
|
1459
|
+
if (BOOST_LIKELY(this != &x)) {
|
|
1460
|
+
//We know resources can be transferred at comiple time if both allocators are
|
|
1461
|
+
//always equal or the allocator is going to be propagated
|
|
1462
|
+
const bool can_steal_resources_alloc
|
|
1463
|
+
= allocator_traits_type::propagate_on_container_move_assignment::value
|
|
1464
|
+
|| allocator_traits_type::is_always_equal::value;
|
|
1465
|
+
dtl::bool_<can_steal_resources_alloc> flag;
|
|
1466
|
+
this->priv_move_assign(boost::move(x), flag);
|
|
1467
|
+
}
|
|
1468
|
+
return *this;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
1472
|
+
inline deque_impl& operator=(std::initializer_list<value_type> il)
|
|
1473
|
+
{
|
|
1474
|
+
this->assign(il.begin(), il.end());
|
|
1475
|
+
return *this;
|
|
1476
|
+
}
|
|
1477
|
+
#endif
|
|
1478
|
+
|
|
1479
|
+
inline void assign(size_type n, const T& val)
|
|
1480
|
+
{
|
|
1481
|
+
dtl::insert_n_copies_proxy<ValAllocator> proxy(val);
|
|
1482
|
+
this->priv_assign(n, proxy);
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
template <class InIt>
|
|
1486
|
+
void assign(InIt first, InIt last
|
|
1487
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1488
|
+
, typename dtl::disable_if_or
|
|
1489
|
+
< void
|
|
1490
|
+
, dtl::is_convertible<InIt, size_type>
|
|
1491
|
+
, dtl::is_not_input_iterator<InIt>
|
|
1492
|
+
>::type * = 0
|
|
1493
|
+
#endif
|
|
1494
|
+
)
|
|
1495
|
+
{
|
|
1496
|
+
iterator cur = this->begin();
|
|
1497
|
+
for ( ; first != last && cur != end(); ++cur, ++first){
|
|
1498
|
+
*cur = *first;
|
|
1499
|
+
}
|
|
1500
|
+
if (first == last){
|
|
1501
|
+
this->erase(cur, this->cend());
|
|
1502
|
+
}
|
|
1503
|
+
else{
|
|
1504
|
+
this->insert(this->cend(), first, last);
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1509
|
+
template <class FwdIt>
|
|
1510
|
+
void assign(FwdIt first, FwdIt last
|
|
1511
|
+
, typename dtl::disable_if_or
|
|
1512
|
+
< void
|
|
1513
|
+
, dtl::is_convertible<FwdIt, size_type>
|
|
1514
|
+
, dtl::is_input_iterator<FwdIt>
|
|
1515
|
+
>::type * = 0
|
|
1516
|
+
)
|
|
1517
|
+
{
|
|
1518
|
+
typedef typename iter_size<FwdIt>::type it_size_type;
|
|
1519
|
+
const it_size_type sz = boost::container::iterator_udistance(first, last);
|
|
1520
|
+
if (BOOST_UNLIKELY(sz > size_type(-1))){
|
|
1521
|
+
boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
|
|
1522
|
+
}
|
|
1523
|
+
const size_type n = static_cast<size_type>(sz);
|
|
1524
|
+
dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
|
|
1525
|
+
this->priv_assign(n, proxy);
|
|
1526
|
+
}
|
|
1527
|
+
#endif
|
|
1528
|
+
|
|
1529
|
+
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
1530
|
+
inline void assign(std::initializer_list<value_type> il)
|
|
1531
|
+
{ this->assign(il.begin(), il.end()); }
|
|
1532
|
+
#endif
|
|
1533
|
+
|
|
1534
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1535
|
+
allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1536
|
+
{ return Base::alloc(); }
|
|
1537
|
+
|
|
1538
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1539
|
+
const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1540
|
+
{ return Base::alloc(); }
|
|
1541
|
+
|
|
1542
|
+
//////////////////////////////////////////////
|
|
1543
|
+
//
|
|
1544
|
+
// iterators
|
|
1545
|
+
//
|
|
1546
|
+
//////////////////////////////////////////////
|
|
1547
|
+
|
|
1548
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1549
|
+
stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1550
|
+
{ return Base::alloc(); }
|
|
1551
|
+
|
|
1552
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1553
|
+
iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1554
|
+
{ return this->prot_start(); }
|
|
1555
|
+
|
|
1556
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1557
|
+
const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1558
|
+
{ return this->prot_start(); }
|
|
1559
|
+
|
|
1560
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1561
|
+
iterator end() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1562
|
+
{ return this->prot_finish(); }
|
|
1563
|
+
|
|
1564
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1565
|
+
const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1566
|
+
{ return this->prot_finish(); }
|
|
1567
|
+
|
|
1568
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1569
|
+
reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1570
|
+
{ return reverse_iterator(this->prot_finish()); }
|
|
1571
|
+
|
|
1572
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1573
|
+
const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1574
|
+
{ return const_reverse_iterator(this->prot_finish()); }
|
|
1575
|
+
|
|
1576
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1577
|
+
reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1578
|
+
{ return reverse_iterator(this->prot_start()); }
|
|
1579
|
+
|
|
1580
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1581
|
+
const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1582
|
+
{ return const_reverse_iterator(this->prot_start()); }
|
|
1583
|
+
|
|
1584
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1585
|
+
const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1586
|
+
{ return this->prot_start(); }
|
|
1587
|
+
|
|
1588
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1589
|
+
const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1590
|
+
{ return this->prot_finish(); }
|
|
1591
|
+
|
|
1592
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1593
|
+
const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1594
|
+
{ return const_reverse_iterator(this->prot_finish()); }
|
|
1595
|
+
|
|
1596
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1597
|
+
const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1598
|
+
{ return const_reverse_iterator(this->prot_start()); }
|
|
1599
|
+
|
|
1600
|
+
//////////////////////////////////////////////
|
|
1601
|
+
//
|
|
1602
|
+
// capacity
|
|
1603
|
+
//
|
|
1604
|
+
//////////////////////////////////////////////
|
|
1605
|
+
|
|
1606
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1607
|
+
bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1608
|
+
{ return this->prot_empty(); }
|
|
1609
|
+
|
|
1610
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1611
|
+
size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1612
|
+
{ return this->prot_size(); }
|
|
1613
|
+
|
|
1614
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1615
|
+
size_type back_capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1616
|
+
{ return size_type(this->size() + this->prot_back_free_capacity()); }
|
|
1617
|
+
|
|
1618
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1619
|
+
size_type front_capacity() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1620
|
+
{ return size_type(this->size() + this->prot_front_free_capacity()); }
|
|
1621
|
+
|
|
1622
|
+
void reserve_back(size_type n)
|
|
1623
|
+
{
|
|
1624
|
+
(void)n;
|
|
1625
|
+
BOOST_IF_CONSTEXPR(is_reservable){
|
|
1626
|
+
const size_type cur_back_cap = this->back_capacity();
|
|
1627
|
+
if (cur_back_cap < n)
|
|
1628
|
+
this->priv_reserve_elements_at_back(size_type(n - cur_back_cap) );
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
void reserve_front(size_type n)
|
|
1633
|
+
{
|
|
1634
|
+
BOOST_CONTAINER_STATIC_ASSERT(!is_single_ended);
|
|
1635
|
+
(void)n;
|
|
1636
|
+
BOOST_IF_CONSTEXPR(is_reservable){
|
|
1637
|
+
const size_type cur_front_cap = this->front_capacity();
|
|
1638
|
+
if (cur_front_cap < n)
|
|
1639
|
+
this->priv_reserve_elements_at_front(size_type(n - cur_front_cap) );
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1644
|
+
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1645
|
+
{ return allocator_traits_type::max_size(this->alloc()); }
|
|
1646
|
+
|
|
1647
|
+
void resize(size_type new_size)
|
|
1648
|
+
{
|
|
1649
|
+
const size_type len = this->size();
|
|
1650
|
+
if (new_size < len)
|
|
1651
|
+
this->priv_erase_last_n(size_type(len - new_size));
|
|
1652
|
+
else{
|
|
1653
|
+
const size_type n = size_type(new_size - this->size());
|
|
1654
|
+
dtl::insert_value_initialized_n_proxy<ValAllocator> proxy;
|
|
1655
|
+
this->priv_insert_back_aux_impl(n, proxy);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
void resize(size_type new_size, default_init_t)
|
|
1660
|
+
{
|
|
1661
|
+
const size_type len = size();
|
|
1662
|
+
if (new_size < len)
|
|
1663
|
+
this->priv_erase_last_n(size_type(len - new_size));
|
|
1664
|
+
else{
|
|
1665
|
+
const size_type n = size_type(new_size - this->size());
|
|
1666
|
+
dtl::insert_default_initialized_n_proxy<ValAllocator> proxy;
|
|
1667
|
+
this->priv_insert_back_aux_impl(n, proxy);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
void resize(size_type new_size, const value_type& x)
|
|
1672
|
+
{
|
|
1673
|
+
const size_type sz = this->size();
|
|
1674
|
+
if (new_size < sz)
|
|
1675
|
+
this->priv_erase_last_n(size_type(sz - new_size));
|
|
1676
|
+
else {
|
|
1677
|
+
const size_type n = size_type(new_size - sz);
|
|
1678
|
+
dtl::insert_n_copies_proxy<ValAllocator> proxy(x);
|
|
1679
|
+
this->priv_insert_back_aux_impl(n, proxy);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
void shrink_to_fit()
|
|
1684
|
+
{
|
|
1685
|
+
//This deque implementation already
|
|
1686
|
+
//deallocates excess nodes when erasing
|
|
1687
|
+
//so there is nothing to do except for
|
|
1688
|
+
//empty deque
|
|
1689
|
+
if(this->empty()){
|
|
1690
|
+
this->prot_clear_map();
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
//////////////////////////////////////////////
|
|
1695
|
+
//
|
|
1696
|
+
// element access
|
|
1697
|
+
//
|
|
1698
|
+
//////////////////////////////////////////////
|
|
1699
|
+
|
|
1700
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1701
|
+
reference front() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1702
|
+
{
|
|
1703
|
+
BOOST_ASSERT(!this->empty());
|
|
1704
|
+
return *this->prot_start_cur_unchecked();
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1708
|
+
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1709
|
+
{
|
|
1710
|
+
BOOST_ASSERT(!this->empty());
|
|
1711
|
+
return *this->prot_start_cur_unchecked();
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1715
|
+
reference back() BOOST_NOEXCEPT_OR_NOTHROW
|
|
1716
|
+
{
|
|
1717
|
+
BOOST_ASSERT(!this->empty());
|
|
1718
|
+
return *this->prot_last_cur_unchecked();
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1722
|
+
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1723
|
+
{
|
|
1724
|
+
BOOST_ASSERT(!this->empty());
|
|
1725
|
+
return *this->prot_last_cur_unchecked();
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1729
|
+
reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
1730
|
+
{
|
|
1731
|
+
BOOST_ASSERT(this->size() > n);
|
|
1732
|
+
return *this->prot_nth(n);
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1736
|
+
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1737
|
+
{
|
|
1738
|
+
BOOST_ASSERT(this->size() > n);
|
|
1739
|
+
return *this->prot_nth(n);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1743
|
+
iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
|
1744
|
+
{
|
|
1745
|
+
BOOST_ASSERT(this->size() >= n);
|
|
1746
|
+
return this->prot_nth(n);
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1750
|
+
const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1751
|
+
{
|
|
1752
|
+
BOOST_ASSERT(this->size() >= n);
|
|
1753
|
+
return this->prot_nth(n);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1757
|
+
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
|
1758
|
+
{
|
|
1759
|
+
//Range checked priv_index_of
|
|
1760
|
+
return this->priv_index_of(p);
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1764
|
+
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
|
1765
|
+
{
|
|
1766
|
+
//Range checked priv_index_of
|
|
1767
|
+
return this->priv_index_of(p);
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1771
|
+
reference at(size_type n)
|
|
1772
|
+
{
|
|
1773
|
+
this->priv_throw_if_out_of_range(n);
|
|
1774
|
+
return (*this)[n];
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
1778
|
+
const_reference at(size_type n) const
|
|
1779
|
+
{
|
|
1780
|
+
this->priv_throw_if_out_of_range(n);
|
|
1781
|
+
return (*this)[n];
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
//////////////////////////////////////////////
|
|
1785
|
+
//
|
|
1786
|
+
// modifiers
|
|
1787
|
+
//
|
|
1788
|
+
//////////////////////////////////////////////
|
|
1789
|
+
|
|
1790
|
+
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1791
|
+
|
|
1792
|
+
template <class... Args>
|
|
1793
|
+
reference emplace_front(BOOST_FWD_REF(Args)... args)
|
|
1794
|
+
{
|
|
1795
|
+
BOOST_ASSERT(!is_single_ended);
|
|
1796
|
+
value_type *const pr = this->prot_push_front_simple_pos();
|
|
1797
|
+
if(BOOST_LIKELY(pr != 0)){
|
|
1798
|
+
allocator_traits_type::construct
|
|
1799
|
+
( this->alloc()
|
|
1800
|
+
, pr
|
|
1801
|
+
, boost::forward<Args>(args)...);
|
|
1802
|
+
this->members_.dec_start();
|
|
1803
|
+
return *pr;
|
|
1804
|
+
}
|
|
1805
|
+
else{
|
|
1806
|
+
typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
|
|
1807
|
+
return *this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
template <class... Args>
|
|
1812
|
+
reference emplace_back(BOOST_FWD_REF(Args)... args)
|
|
1813
|
+
{
|
|
1814
|
+
value_type *const pr = this->prot_push_back_simple_pos();
|
|
1815
|
+
if(BOOST_LIKELY(pr != 0)){
|
|
1816
|
+
allocator_traits_type::construct
|
|
1817
|
+
( this->alloc(), pr, boost::forward<Args>(args)...);
|
|
1818
|
+
this->prot_inc_finish();
|
|
1819
|
+
return *pr;
|
|
1820
|
+
}
|
|
1821
|
+
else{
|
|
1822
|
+
typedef dtl::insert_nonmovable_emplace_proxy<ValAllocator, Args...> type;
|
|
1823
|
+
return *this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
template <class... Args>
|
|
1828
|
+
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
|
|
1829
|
+
{
|
|
1830
|
+
const size_type elemsbefore = this->prot_it_to_start_off(p);
|
|
1831
|
+
const size_type length = this->prot_size();
|
|
1832
|
+
|
|
1833
|
+
if (elemsbefore == length) {
|
|
1834
|
+
this->emplace_back(boost::forward<Args>(args)...);
|
|
1835
|
+
return this->prot_back_it();
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
BOOST_IF_CONSTEXPR(!is_single_ended)
|
|
1839
|
+
if (!elemsbefore) {
|
|
1840
|
+
this->emplace_front(boost::forward<Args>(args)...);
|
|
1841
|
+
return this->begin();
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
typedef dtl::insert_emplace_proxy<ValAllocator, Args...> type;
|
|
1845
|
+
return this->priv_insert_middle_aux_impl(elemsbefore, 1, type(boost::forward<Args>(args)...));
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
1849
|
+
|
|
1850
|
+
#define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
|
|
1851
|
+
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
|
|
1852
|
+
reference emplace_front(BOOST_MOVE_UREF##N)\
|
|
1853
|
+
{\
|
|
1854
|
+
value_type *const pr = this->prot_push_front_simple_pos();\
|
|
1855
|
+
if(BOOST_LIKELY(pr != 0)){\
|
|
1856
|
+
allocator_traits_type::construct\
|
|
1857
|
+
( this->alloc(), pr BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
|
1858
|
+
this->members_.dec_start();\
|
|
1859
|
+
return *pr;\
|
|
1860
|
+
}\
|
|
1861
|
+
else{\
|
|
1862
|
+
typedef dtl::insert_nonmovable_emplace_proxy##N\
|
|
1863
|
+
<ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
|
|
1864
|
+
return *priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
|
|
1865
|
+
}\
|
|
1866
|
+
}\
|
|
1867
|
+
\
|
|
1868
|
+
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
|
|
1869
|
+
reference emplace_back(BOOST_MOVE_UREF##N)\
|
|
1870
|
+
{\
|
|
1871
|
+
value_type * const pr = this->prot_push_back_simple_pos();\
|
|
1872
|
+
if(BOOST_LIKELY(pr != 0)){\
|
|
1873
|
+
allocator_traits_type::construct\
|
|
1874
|
+
( this->alloc(), pr BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
|
1875
|
+
this->prot_inc_finish();\
|
|
1876
|
+
return *pr;\
|
|
1877
|
+
}\
|
|
1878
|
+
else{\
|
|
1879
|
+
typedef dtl::insert_nonmovable_emplace_proxy##N\
|
|
1880
|
+
<ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
|
|
1881
|
+
return *priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
|
|
1882
|
+
}\
|
|
1883
|
+
}\
|
|
1884
|
+
\
|
|
1885
|
+
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
|
|
1886
|
+
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
|
1887
|
+
{\
|
|
1888
|
+
const size_type elemsbefore = this->prot_it_to_start_off(p);\
|
|
1889
|
+
const size_type length = this->prot_size();\
|
|
1890
|
+
\
|
|
1891
|
+
BOOST_IF_CONSTEXPR(!is_single_ended)\
|
|
1892
|
+
if (!elemsbefore) {\
|
|
1893
|
+
this->emplace_front(BOOST_MOVE_FWD##N);\
|
|
1894
|
+
return this->begin();\
|
|
1895
|
+
}\
|
|
1896
|
+
\
|
|
1897
|
+
if (elemsbefore == length) {\
|
|
1898
|
+
this->emplace_back(BOOST_MOVE_FWD##N);\
|
|
1899
|
+
return this->prot_back_it();\
|
|
1900
|
+
}\
|
|
1901
|
+
else {\
|
|
1902
|
+
typedef dtl::insert_emplace_proxy_arg##N\
|
|
1903
|
+
<ValAllocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
|
|
1904
|
+
return this->priv_insert_middle_aux_impl(elemsbefore, 1, type(BOOST_MOVE_FWD##N));\
|
|
1905
|
+
}\
|
|
1906
|
+
}\
|
|
1907
|
+
//
|
|
1908
|
+
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
|
|
1909
|
+
#undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
|
|
1910
|
+
|
|
1911
|
+
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
1912
|
+
|
|
1913
|
+
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1914
|
+
void push_front(const T &x);
|
|
1915
|
+
|
|
1916
|
+
void push_front(T &&x);
|
|
1917
|
+
#else
|
|
1918
|
+
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
|
|
1919
|
+
#endif
|
|
1920
|
+
|
|
1921
|
+
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1922
|
+
void push_back(const T &x);
|
|
1923
|
+
|
|
1924
|
+
void push_back(T &&x);
|
|
1925
|
+
#else
|
|
1926
|
+
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
|
|
1927
|
+
#endif
|
|
1928
|
+
|
|
1929
|
+
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1930
|
+
|
|
1931
|
+
iterator insert(const_iterator p, const T &x);
|
|
1932
|
+
|
|
1933
|
+
iterator insert(const_iterator p, T &&x);
|
|
1934
|
+
#else
|
|
1935
|
+
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
|
|
1936
|
+
#endif
|
|
1937
|
+
|
|
1938
|
+
inline iterator insert(const_iterator pos, size_type n, const value_type& x)
|
|
1939
|
+
{
|
|
1940
|
+
BOOST_ASSERT(this->priv_in_range_or_end(pos));
|
|
1941
|
+
dtl::insert_n_copies_proxy<ValAllocator> proxy(x);
|
|
1942
|
+
return this->priv_insert_aux_impl(pos, n, proxy);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
template <class InIt>
|
|
1946
|
+
iterator insert(const_iterator pos, InIt first, InIt last
|
|
1947
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1948
|
+
, typename dtl::disable_if_or
|
|
1949
|
+
< void
|
|
1950
|
+
, dtl::is_convertible<InIt, size_type>
|
|
1951
|
+
, dtl::is_not_input_iterator<InIt>
|
|
1952
|
+
>::type * = 0
|
|
1953
|
+
#endif
|
|
1954
|
+
)
|
|
1955
|
+
{
|
|
1956
|
+
BOOST_ASSERT(this->priv_in_range_or_end(pos));
|
|
1957
|
+
size_type n = 0;
|
|
1958
|
+
iterator it(pos.unconst());
|
|
1959
|
+
for(;first != last; ++first, ++n){
|
|
1960
|
+
it = this->emplace(it, *first);
|
|
1961
|
+
++it;
|
|
1962
|
+
}
|
|
1963
|
+
it -= difference_type(n);
|
|
1964
|
+
return it;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
1968
|
+
inline iterator insert(const_iterator pos, std::initializer_list<value_type> il)
|
|
1969
|
+
{
|
|
1970
|
+
//Range check os pos is done in insert()
|
|
1971
|
+
return this->insert(pos, il.begin(), il.end());
|
|
1972
|
+
}
|
|
1973
|
+
#endif
|
|
1974
|
+
|
|
1975
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1976
|
+
template <class FwdIt>
|
|
1977
|
+
inline iterator insert(const_iterator p, FwdIt first, FwdIt last
|
|
1978
|
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
1979
|
+
, typename dtl::disable_if_or
|
|
1980
|
+
< void
|
|
1981
|
+
, dtl::is_convertible<FwdIt, size_type>
|
|
1982
|
+
, dtl::is_input_iterator<FwdIt>
|
|
1983
|
+
>::type * = 0
|
|
1984
|
+
#endif
|
|
1985
|
+
)
|
|
1986
|
+
{
|
|
1987
|
+
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
|
1988
|
+
|
|
1989
|
+
typedef typename iter_size<FwdIt>::type it_size_type;
|
|
1990
|
+
const it_size_type sz = boost::container::iterator_udistance(first, last);
|
|
1991
|
+
if (BOOST_UNLIKELY(sz > size_type(-1))){
|
|
1992
|
+
boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
|
|
1993
|
+
}
|
|
1994
|
+
const size_type n = static_cast<size_type>(sz);
|
|
1995
|
+
|
|
1996
|
+
dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
|
|
1997
|
+
return this->priv_insert_aux_impl(p, n, proxy);
|
|
1998
|
+
}
|
|
1999
|
+
#endif
|
|
2000
|
+
|
|
2001
|
+
void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
|
|
2002
|
+
{
|
|
2003
|
+
BOOST_ASSERT(!is_single_ended);
|
|
2004
|
+
BOOST_ASSERT(!this->empty());
|
|
2005
|
+
if (BOOST_LIKELY(this->prot_pop_front_simple_available())) {
|
|
2006
|
+
allocator_traits_type::destroy
|
|
2007
|
+
( this->alloc()
|
|
2008
|
+
, boost::movelib::to_raw_pointer(this->prot_start_cur_unchecked())
|
|
2009
|
+
);
|
|
2010
|
+
this->members_.inc_start();
|
|
2011
|
+
}
|
|
2012
|
+
else
|
|
2013
|
+
this->priv_pop_front_aux();
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
|
|
2017
|
+
{
|
|
2018
|
+
BOOST_ASSERT(!this->empty());
|
|
2019
|
+
if (BOOST_LIKELY(this->prot_pop_back_simple_available())) {
|
|
2020
|
+
this->prot_dec_finish();
|
|
2021
|
+
allocator_traits_type::destroy
|
|
2022
|
+
( this->alloc()
|
|
2023
|
+
, boost::movelib::to_raw_pointer(this->prot_finish_cur_unchecked())
|
|
2024
|
+
);
|
|
2025
|
+
}
|
|
2026
|
+
else
|
|
2027
|
+
this->priv_pop_back_aux();
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
|
|
2031
|
+
{
|
|
2032
|
+
BOOST_ASSERT(this->priv_in_range(pos));
|
|
2033
|
+
iterator next = pos.unconst();
|
|
2034
|
+
++next;
|
|
2035
|
+
const size_type index = this->prot_it_to_start_off(pos);
|
|
2036
|
+
const size_type sz = this->prot_size();
|
|
2037
|
+
|
|
2038
|
+
BOOST_IF_CONSTEXPR(!is_single_ended)
|
|
2039
|
+
if (index < sz/2u) {
|
|
2040
|
+
this->priv_segmented_move_backward_n(pos.unconst(), index, next);
|
|
2041
|
+
this->pop_front();
|
|
2042
|
+
return next;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
this->priv_segmented_move_n(next, size_type(sz - size_type(index + 1u)), pos.unconst());
|
|
2046
|
+
this->pop_back();
|
|
2047
|
+
return pos.unconst();
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
|
2051
|
+
{
|
|
2052
|
+
BOOST_ASSERT(first == last ||
|
|
2053
|
+
(first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
|
|
2054
|
+
const size_type n = static_cast<size_type>(last - first);
|
|
2055
|
+
if (n == this->prot_size()) {
|
|
2056
|
+
this->clear();
|
|
2057
|
+
return this->end();
|
|
2058
|
+
}
|
|
2059
|
+
else {
|
|
2060
|
+
const size_type elems_before = this->prot_it_to_start_off(first);
|
|
2061
|
+
const size_type elems_after = size_type(this->prot_size() - n - elems_before);
|
|
2062
|
+
|
|
2063
|
+
BOOST_IF_CONSTEXPR(!is_single_ended)
|
|
2064
|
+
if (elems_before < elems_after) {
|
|
2065
|
+
const iterator old_start = this->begin();
|
|
2066
|
+
iterator new_start = this->priv_segmented_move_backward_n(first.unconst(), elems_before, last.unconst());
|
|
2067
|
+
this->prot_destroy_range(old_start, new_start);
|
|
2068
|
+
this->prot_deallocate_nodes_if_not_reservable(old_start.get_node(), new_start.m_node);
|
|
2069
|
+
this->members_.inc_start(n);
|
|
2070
|
+
return this->nth(elems_before);
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
const iterator old_finish = this->end();
|
|
2074
|
+
iterator new_finish = this->priv_segmented_move_n(last.unconst(), elems_after, first.unconst());
|
|
2075
|
+
this->prot_destroy_range(new_finish, old_finish);
|
|
2076
|
+
this->prot_deallocate_nodes_if_not_reservable(new_finish.m_node + 1, old_finish.get_node() + 1);
|
|
2077
|
+
this->prot_dec_finish(n);
|
|
2078
|
+
return this->nth(elems_before);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
inline void swap(deque_impl &x)
|
|
2083
|
+
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
|
|
2084
|
+
|| allocator_traits_type::is_always_equal::value)
|
|
2085
|
+
{
|
|
2086
|
+
this->swap_members(x);
|
|
2087
|
+
dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
|
2088
|
+
dtl::swap_alloc(this->alloc(), x.alloc(), flag);
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
void clear() BOOST_NOEXCEPT_OR_NOTHROW
|
|
2092
|
+
{
|
|
2093
|
+
if (!this->empty()) {
|
|
2094
|
+
const iterator start = this->prot_start();
|
|
2095
|
+
const iterator finish = this->prot_finish();
|
|
2096
|
+
const index_pointer start_node = start.get_node();
|
|
2097
|
+
const index_pointer finish_node = finish.get_node();
|
|
2098
|
+
for (index_pointer node = start_node + 1; node < finish_node; ++node) {
|
|
2099
|
+
this->prot_destroy_range(*node, *node + get_block_ssize());
|
|
2100
|
+
this->prot_deallocate_node_if_not_reservable(*node);
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
if (start_node != finish_node) {
|
|
2104
|
+
this->prot_destroy_range(start.get_cur(), start.get_last());
|
|
2105
|
+
this->prot_destroy_range(finish.get_first(), finish.get_cur());
|
|
2106
|
+
this->prot_deallocate_node_if_not_reservable(finish.get_first());
|
|
2107
|
+
}
|
|
2108
|
+
else
|
|
2109
|
+
this->prot_destroy_range(start.get_cur(), finish.get_cur());
|
|
2110
|
+
|
|
2111
|
+
this->prot_reset_finish_to_start();
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
2116
|
+
friend bool operator==(const deque_impl& x, const deque_impl& y)
|
|
2117
|
+
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
|
|
2118
|
+
|
|
2119
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
2120
|
+
friend bool operator!=(const deque_impl& x, const deque_impl& y)
|
|
2121
|
+
{ return !(x == y); }
|
|
2122
|
+
|
|
2123
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
2124
|
+
friend bool operator<(const deque_impl& x, const deque_impl& y)
|
|
2125
|
+
{ return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
|
2126
|
+
|
|
2127
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
2128
|
+
friend bool operator>(const deque_impl& x, const deque_impl& y)
|
|
2129
|
+
{ return y < x; }
|
|
2130
|
+
|
|
2131
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
2132
|
+
friend bool operator<=(const deque_impl& x, const deque_impl& y)
|
|
2133
|
+
{ return !(y < x); }
|
|
2134
|
+
|
|
2135
|
+
BOOST_CONTAINER_NODISCARD inline
|
|
2136
|
+
friend bool operator>=(const deque_impl& x, const deque_impl& y)
|
|
2137
|
+
{ return !(x < y); }
|
|
2138
|
+
|
|
2139
|
+
inline friend void swap(deque_impl& x, deque_impl& y)
|
|
2140
|
+
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
|
|
2141
|
+
{ x.swap(y); }
|
|
2142
|
+
|
|
2143
|
+
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
2144
|
+
private:
|
|
2145
|
+
|
|
2146
|
+
template <class InsertProxy>
|
|
2147
|
+
void priv_assign(size_type n, InsertProxy proxy)
|
|
2148
|
+
{
|
|
2149
|
+
const size_type sz = this->prot_size();
|
|
2150
|
+
this->priv_segmented_proxy_copy_n_and_update(this->begin(), sz < n ? sz : n, proxy);
|
|
2151
|
+
if (n > sz) {
|
|
2152
|
+
this->priv_insert_back_aux_impl(size_type(n - sz), proxy);
|
|
2153
|
+
}
|
|
2154
|
+
else{
|
|
2155
|
+
this->priv_erase_last_n(size_type(sz - n));
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
void priv_move_assign(BOOST_RV_REF(deque_impl) x, dtl::bool_<true> /*steal_resources*/)
|
|
2160
|
+
{
|
|
2161
|
+
//Destroy objects but retain memory in case x reuses it in the future
|
|
2162
|
+
this->clear();
|
|
2163
|
+
//Move allocator if needed
|
|
2164
|
+
dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
|
|
2165
|
+
dtl::move_alloc(this->alloc(), x.alloc(), flag);
|
|
2166
|
+
//Nothrow swap
|
|
2167
|
+
this->swap_members(x);
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
void priv_move_assign(BOOST_RV_REF(deque_impl) x, dtl::bool_<false> /*steal_resources*/)
|
|
2171
|
+
{
|
|
2172
|
+
//We can't guarantee a compile-time equal allocator or propagation so fallback to runtime
|
|
2173
|
+
//Resources can be transferred if both allocators are equal
|
|
2174
|
+
if (this->alloc() == x.alloc()) {
|
|
2175
|
+
this->priv_move_assign(boost::move(x), dtl::true_());
|
|
2176
|
+
}
|
|
2177
|
+
else {
|
|
2178
|
+
this->assign(boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
inline size_type priv_index_of(const_iterator p) const
|
|
2183
|
+
{
|
|
2184
|
+
BOOST_ASSERT(this->cbegin() <= p);
|
|
2185
|
+
BOOST_ASSERT(p <= this->cend());
|
|
2186
|
+
return this->prot_it_to_start_off(p);
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
void priv_erase_last_n(size_type n)
|
|
2190
|
+
{
|
|
2191
|
+
const size_type sz = this->prot_size();
|
|
2192
|
+
BOOST_ASSERT(n <= sz);
|
|
2193
|
+
|
|
2194
|
+
if(sz) {
|
|
2195
|
+
const iterator old_finish = this->prot_finish();
|
|
2196
|
+
const iterator new_finish = old_finish - difference_type(n);
|
|
2197
|
+
this->prot_destroy_range(new_finish, old_finish);
|
|
2198
|
+
this->prot_deallocate_nodes_if_not_reservable(new_finish.get_node() + 1, old_finish.get_node() + 1);
|
|
2199
|
+
this->prot_dec_finish(n);
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
void priv_throw_if_out_of_range(size_type n) const
|
|
2204
|
+
{
|
|
2205
|
+
if (n >= this->size())
|
|
2206
|
+
throw_out_of_range("deque::at out of range");
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
inline bool priv_in_range(const_iterator pos) const
|
|
2210
|
+
{
|
|
2211
|
+
return (this->begin() <= pos) && (pos < this->end());
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
inline bool priv_in_range_or_end(const_iterator pos) const
|
|
2215
|
+
{
|
|
2216
|
+
return (this->begin() <= pos) && (pos <= this->end());
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
template <class U>
|
|
2220
|
+
BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
|
|
2221
|
+
{
|
|
2222
|
+
return this->emplace(p, ::boost::forward<U>(x));
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
template <class U>
|
|
2226
|
+
BOOST_CONTAINER_FORCEINLINE void priv_push_back(BOOST_FWD_REF(U) u)
|
|
2227
|
+
{
|
|
2228
|
+
this->emplace_back(::boost::forward<U>(u));
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
template <class U>
|
|
2232
|
+
BOOST_CONTAINER_FORCEINLINE void priv_push_front(BOOST_FWD_REF(U) u)
|
|
2233
|
+
{
|
|
2234
|
+
this->emplace_front(::boost::forward<U>(u));
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
void prot_destroy_range(iterator start, iterator finish)
|
|
2238
|
+
{
|
|
2239
|
+
(void)start; (void)finish;
|
|
2240
|
+
BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
|
|
2241
|
+
const index_pointer start_node = start.get_node();
|
|
2242
|
+
const index_pointer finish_node = finish.get_node();
|
|
2243
|
+
|
|
2244
|
+
//In a sane deque both should be null or non-null
|
|
2245
|
+
BOOST_ASSERT(!start_node == !finish_node);
|
|
2246
|
+
if(start_node){
|
|
2247
|
+
for (index_pointer node = start_node + 1; node < finish_node; ++node) {
|
|
2248
|
+
this->prot_destroy_range(*node, *node + get_block_ssize());
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
if (start_node != finish_node) {
|
|
2252
|
+
this->prot_destroy_range(start.get_cur(), start.get_last());
|
|
2253
|
+
this->prot_destroy_range(finish.get_first(), finish.get_cur());
|
|
2254
|
+
}
|
|
2255
|
+
else
|
|
2256
|
+
this->prot_destroy_range(start.get_cur(), finish.get_cur());
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
void prot_destroy_range(pointer p, pointer p2)
|
|
2262
|
+
{
|
|
2263
|
+
(void)p; (void)p2;
|
|
2264
|
+
BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
|
|
2265
|
+
for(;p != p2; ++p){
|
|
2266
|
+
allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
template<class InsertProxy>
|
|
2272
|
+
iterator priv_insert_middle_aux_impl(const size_type elemsbefore, const size_type n, InsertProxy proxy)
|
|
2273
|
+
{
|
|
2274
|
+
typedef dtl::bool_<dtl::is_single_value_proxy<InsertProxy>::value> single_t;
|
|
2275
|
+
BOOST_ASSERT(!single_t::value || n == 1);
|
|
2276
|
+
|
|
2277
|
+
const size_type length = this->prot_size();
|
|
2278
|
+
|
|
2279
|
+
BOOST_IF_CONSTEXPR(!is_single_ended)
|
|
2280
|
+
if (elemsbefore < length / 2) {
|
|
2281
|
+
this->priv_reserve_elements_at_front(n);
|
|
2282
|
+
const iterator old_start = this->prot_start();
|
|
2283
|
+
iterator new_start = old_start;
|
|
2284
|
+
priv_itsub(new_start, n, single_t());
|
|
2285
|
+
|
|
2286
|
+
BOOST_ASSERT(!single_t::value || elemsbefore >= 1);
|
|
2287
|
+
|
|
2288
|
+
if(single_t::value || elemsbefore >= n) {
|
|
2289
|
+
iterator start_n = old_start;
|
|
2290
|
+
priv_itadd(start_n, n, single_t());
|
|
2291
|
+
BOOST_CONTAINER_TRY {
|
|
2292
|
+
this->priv_segmented_uninitialized_move_alloc_n(old_start, n, new_start, single_t());
|
|
2293
|
+
}
|
|
2294
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2295
|
+
this->prot_deallocate_nodes_if_not_reservable(new_start.m_node, old_start.m_node);
|
|
2296
|
+
BOOST_CONTAINER_RETHROW
|
|
2297
|
+
}
|
|
2298
|
+
BOOST_CONTAINER_CATCH_END
|
|
2299
|
+
|
|
2300
|
+
this->members_.dec_start(n);
|
|
2301
|
+
iterator p = this->priv_segmented_move_n(start_n, size_type(elemsbefore - n), old_start);
|
|
2302
|
+
this->priv_segmented_proxy_copy_n_and_update(p, n, proxy);
|
|
2303
|
+
return p;
|
|
2304
|
+
}
|
|
2305
|
+
else {
|
|
2306
|
+
const size_type mid_count = size_type(n - elemsbefore);
|
|
2307
|
+
iterator mid_start = old_start - difference_type(mid_count);
|
|
2308
|
+
|
|
2309
|
+
BOOST_CONTAINER_TRY {
|
|
2310
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(mid_start, mid_count, proxy);
|
|
2311
|
+
this->members_.dec_start(mid_count);
|
|
2312
|
+
this->priv_segmented_uninitialized_move_alloc_n(old_start, elemsbefore, new_start);
|
|
2313
|
+
}
|
|
2314
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2315
|
+
this->prot_deallocate_nodes_if_not_reservable(new_start.m_node, old_start.get_node());
|
|
2316
|
+
BOOST_CONTAINER_RETHROW
|
|
2317
|
+
}
|
|
2318
|
+
BOOST_CONTAINER_CATCH_END
|
|
2319
|
+
this->members_.dec_start(size_type(n - mid_count));
|
|
2320
|
+
this->priv_segmented_proxy_copy_n_and_update(old_start, elemsbefore, proxy);
|
|
2321
|
+
return mid_start;
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
this->priv_reserve_elements_at_back(n);
|
|
2326
|
+
const iterator old_finish = this->prot_finish();
|
|
2327
|
+
const size_type elemsafter = size_type(length - elemsbefore);
|
|
2328
|
+
|
|
2329
|
+
BOOST_ASSERT(!single_t::value || elemsafter >= 1);
|
|
2330
|
+
|
|
2331
|
+
if(single_t::value || elemsafter >= n) {
|
|
2332
|
+
iterator finish_n = old_finish;
|
|
2333
|
+
priv_itsub(finish_n, n, single_t());
|
|
2334
|
+
BOOST_CONTAINER_TRY {
|
|
2335
|
+
this->priv_segmented_uninitialized_move_alloc_n(finish_n, n, old_finish, single_t());
|
|
2336
|
+
}
|
|
2337
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2338
|
+
this->prot_deallocate_nodes_if_not_reservable(old_finish.get_node() + 1, (old_finish + difference_type(n)).m_node + 1);
|
|
2339
|
+
BOOST_CONTAINER_RETHROW
|
|
2340
|
+
}
|
|
2341
|
+
BOOST_CONTAINER_CATCH_END
|
|
2342
|
+
|
|
2343
|
+
this->prot_inc_finish(n);
|
|
2344
|
+
const size_type move_n = size_type(elemsafter - n);
|
|
2345
|
+
this->priv_segmented_move_backward_n(finish_n, move_n, old_finish);
|
|
2346
|
+
finish_n -= difference_type(move_n);
|
|
2347
|
+
this->priv_segmented_proxy_copy_n_and_update(finish_n, n, proxy);
|
|
2348
|
+
return finish_n;
|
|
2349
|
+
}
|
|
2350
|
+
else {
|
|
2351
|
+
const size_type raw_gap = size_type(n - elemsafter);
|
|
2352
|
+
iterator pos = old_finish - difference_type(elemsafter);
|
|
2353
|
+
|
|
2354
|
+
BOOST_CONTAINER_TRY{
|
|
2355
|
+
this->priv_segmented_uninitialized_move_alloc_n(pos, elemsafter, old_finish + difference_type(raw_gap));
|
|
2356
|
+
BOOST_CONTAINER_TRY{
|
|
2357
|
+
this->priv_segmented_proxy_copy_n_and_update(pos, elemsafter, proxy);
|
|
2358
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(old_finish, raw_gap, proxy);
|
|
2359
|
+
}
|
|
2360
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2361
|
+
this->prot_destroy_range(old_finish, old_finish + difference_type(elemsafter));
|
|
2362
|
+
BOOST_CONTAINER_RETHROW
|
|
2363
|
+
}
|
|
2364
|
+
BOOST_CONTAINER_CATCH_END
|
|
2365
|
+
}
|
|
2366
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2367
|
+
this->prot_deallocate_nodes_if_not_reservable(old_finish.get_node() + 1, (old_finish + difference_type(n)).m_node + 1);
|
|
2368
|
+
BOOST_CONTAINER_RETHROW
|
|
2369
|
+
}
|
|
2370
|
+
BOOST_CONTAINER_CATCH_END
|
|
2371
|
+
this->prot_inc_finish(n);
|
|
2372
|
+
return pos;
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
template<class InsertProxy>
|
|
2377
|
+
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
|
|
2378
|
+
{
|
|
2379
|
+
const size_type elemsbefore = this->prot_it_to_start_off(p);
|
|
2380
|
+
|
|
2381
|
+
if (elemsbefore == this->prot_size()) {
|
|
2382
|
+
return this->priv_insert_back_aux_impl(n, proxy);
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
BOOST_IF_CONSTEXPR(!is_single_ended)
|
|
2386
|
+
if(!elemsbefore) {
|
|
2387
|
+
return this->priv_insert_front_aux_impl(n, proxy);
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
return this->priv_insert_middle_aux_impl(elemsbefore, n, proxy);
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
template <class InsertProxy>
|
|
2394
|
+
void priv_segmented_proxy_uninitialized_copy_n_and_update(const iterator first, size_type n, InsertProxy &proxy)
|
|
2395
|
+
{
|
|
2396
|
+
BOOST_IF_CONSTEXPR (dtl::is_single_value_proxy<InsertProxy>::value) {
|
|
2397
|
+
(void)n;
|
|
2398
|
+
proxy.uninitialized_copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(first.get_cur()), 1u);
|
|
2399
|
+
}
|
|
2400
|
+
else if (BOOST_LIKELY(n != 0)){ //We might initialize an empty range and current_node might be null
|
|
2401
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
2402
|
+
|
|
2403
|
+
index_pointer current_node = first.get_node();
|
|
2404
|
+
|
|
2405
|
+
BOOST_CONTAINER_TRY{
|
|
2406
|
+
const pointer cur = first.get_cur();
|
|
2407
|
+
const size_type block = size_type(block_size - size_type(cur - *current_node));
|
|
2408
|
+
size_type cnt = n < block ? n: block;
|
|
2409
|
+
proxy.uninitialized_copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt);
|
|
2410
|
+
n = size_type(n - cnt);
|
|
2411
|
+
|
|
2412
|
+
while (n) {
|
|
2413
|
+
++current_node;
|
|
2414
|
+
cnt = n < block_size ? n: block_size;
|
|
2415
|
+
proxy.uninitialized_copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt);
|
|
2416
|
+
n = size_type(n - cnt);
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2420
|
+
this->prot_destroy_range(first, iterator(*current_node, current_node));
|
|
2421
|
+
BOOST_CONTAINER_RETHROW
|
|
2422
|
+
}
|
|
2423
|
+
BOOST_CONTAINER_CATCH_END
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
template <class InsertProxy>
|
|
2429
|
+
void priv_segmented_proxy_copy_n_and_update(const iterator first, size_type n, InsertProxy &proxy)
|
|
2430
|
+
{
|
|
2431
|
+
BOOST_IF_CONSTEXPR (dtl::is_single_value_proxy<InsertProxy>::value) {
|
|
2432
|
+
(void)n;
|
|
2433
|
+
proxy.copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(first.get_cur()), 1u);
|
|
2434
|
+
}
|
|
2435
|
+
else if (BOOST_LIKELY(n != 0)){ //We might assign an empty range in a default constructed deque
|
|
2436
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
2437
|
+
|
|
2438
|
+
index_pointer current_node = first.get_node();
|
|
2439
|
+
|
|
2440
|
+
const pointer cur = first.get_cur();
|
|
2441
|
+
const size_type block = size_type(block_size - size_type(cur - *current_node));
|
|
2442
|
+
size_type cnt = n < block ? n: block;
|
|
2443
|
+
proxy.copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt);
|
|
2444
|
+
n = size_type(n - cnt);
|
|
2445
|
+
|
|
2446
|
+
while (n) {
|
|
2447
|
+
++current_node;
|
|
2448
|
+
cnt = n < block_size ? n: block_size;
|
|
2449
|
+
proxy.copy_n_and_update(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt);
|
|
2450
|
+
n = size_type(n - cnt);
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
template <class InsertProxy>
|
|
2456
|
+
void priv_insert_segmented_uninitialized_copy_n_and_update(const iterator first, size_type n, InsertProxy proxy)
|
|
2457
|
+
{
|
|
2458
|
+
BOOST_CONTAINER_TRY{
|
|
2459
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(first, n, proxy);
|
|
2460
|
+
}
|
|
2461
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2462
|
+
this->prot_deallocate_nodes_if_not_reservable(first.get_node() + 1, (first+difference_type(n)).get_node() + 1);
|
|
2463
|
+
BOOST_CONTAINER_RETHROW
|
|
2464
|
+
}
|
|
2465
|
+
BOOST_CONTAINER_CATCH_END
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
template<class It>
|
|
2469
|
+
static BOOST_CONTAINER_FORCEINLINE void priv_itadd(It &it, size_type, dtl::bool_<true> /*single element*/)
|
|
2470
|
+
{ ++it; }
|
|
2471
|
+
|
|
2472
|
+
template<class It>
|
|
2473
|
+
static BOOST_CONTAINER_FORCEINLINE void priv_itadd(It &it, size_type n, dtl::bool_<false> /*!single element*/)
|
|
2474
|
+
{ it += difference_type(n); }
|
|
2475
|
+
|
|
2476
|
+
template<class It>
|
|
2477
|
+
static BOOST_CONTAINER_FORCEINLINE void priv_itsub(It &it, size_type, dtl::bool_<true> /*single element*/)
|
|
2478
|
+
{ --it; }
|
|
2479
|
+
|
|
2480
|
+
template<class It>
|
|
2481
|
+
static BOOST_CONTAINER_FORCEINLINE void priv_itsub(It &it, size_type n, dtl::bool_<false> /*!single element*/)
|
|
2482
|
+
{ it -= difference_type(n); }
|
|
2483
|
+
|
|
2484
|
+
void priv_segmented_uninitialized_move_alloc_n(iterator first, size_type n, iterator dest, dtl::bool_<true> /*single element*/)
|
|
2485
|
+
{
|
|
2486
|
+
BOOST_ASSERT(n == 1); (void)n;
|
|
2487
|
+
allocator_traits_type::construct
|
|
2488
|
+
( this->alloc()
|
|
2489
|
+
, boost::movelib::to_raw_pointer(dest.get_cur())
|
|
2490
|
+
, boost::move(*first));
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
void priv_segmented_uninitialized_move_alloc_n(iterator first, size_type n, iterator dest, dtl::bool_<false> /*!single element*/)
|
|
2494
|
+
{
|
|
2495
|
+
if (BOOST_LIKELY(n != 0)) { //Check for empty range, current_node might be null
|
|
2496
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
2497
|
+
|
|
2498
|
+
index_pointer current_node = first.get_node();
|
|
2499
|
+
|
|
2500
|
+
BOOST_CONTAINER_TRY{
|
|
2501
|
+
const pointer cur = first.get_cur();
|
|
2502
|
+
const size_type block = size_type(block_size - size_type(cur - *current_node));
|
|
2503
|
+
size_type cnt = n < block ? n: block;
|
|
2504
|
+
dest = ::boost::container::uninitialized_move_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt, dest);
|
|
2505
|
+
n = size_type(n - cnt);
|
|
2506
|
+
|
|
2507
|
+
while (n) {
|
|
2508
|
+
++current_node;
|
|
2509
|
+
cnt = n < block_size ? n: block_size;
|
|
2510
|
+
dest = ::boost::container::uninitialized_move_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt, dest);
|
|
2511
|
+
n = size_type(n - cnt);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2515
|
+
this->prot_destroy_range(first, iterator(*current_node, current_node));
|
|
2516
|
+
BOOST_CONTAINER_RETHROW
|
|
2517
|
+
}
|
|
2518
|
+
BOOST_CONTAINER_CATCH_END
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
BOOST_CONTAINER_FORCEINLINE void priv_segmented_uninitialized_move_alloc_n(iterator first, size_type n, iterator dest)
|
|
2523
|
+
{
|
|
2524
|
+
this->priv_segmented_uninitialized_move_alloc_n(first, n, dest, dtl::bool_<false>());
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
void priv_segmented_uninitialized_copy_alloc_n(const_iterator first, size_type n, iterator dest)
|
|
2528
|
+
{
|
|
2529
|
+
if (BOOST_LIKELY(n != 0)) { //We might initialize an empty range and current_node might be null
|
|
2530
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
2531
|
+
|
|
2532
|
+
index_pointer current_node = first.get_node();
|
|
2533
|
+
|
|
2534
|
+
BOOST_CONTAINER_TRY{
|
|
2535
|
+
const pointer cur = first.get_cur();
|
|
2536
|
+
const size_type block = size_type(block_size - size_type(cur - *current_node));
|
|
2537
|
+
size_type cnt = n < block ? n: block;
|
|
2538
|
+
dest = ::boost::container::uninitialized_copy_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(cur), cnt, dest);
|
|
2539
|
+
n = size_type(n - cnt);
|
|
2540
|
+
|
|
2541
|
+
while (n) {
|
|
2542
|
+
++current_node;
|
|
2543
|
+
cnt = n < block_size ? n: block_size;
|
|
2544
|
+
dest = ::boost::container::uninitialized_copy_alloc_n(this->alloc(), boost::movelib::to_raw_pointer(*current_node), cnt, dest);
|
|
2545
|
+
n = size_type(n - cnt);
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
BOOST_CONTAINER_CATCH(...) {
|
|
2549
|
+
this->prot_destroy_range(first.unconst(), iterator(*current_node, current_node));
|
|
2550
|
+
BOOST_CONTAINER_RETHROW
|
|
2551
|
+
}
|
|
2552
|
+
BOOST_CONTAINER_CATCH_END
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
static iterator priv_segmented_move_n(const_iterator first, size_type n, iterator dest)
|
|
2557
|
+
{
|
|
2558
|
+
index_pointer current_node = first.get_node();
|
|
2559
|
+
BOOST_ASSERT(current_node != index_pointer());
|
|
2560
|
+
|
|
2561
|
+
const pointer cur = first.get_cur();
|
|
2562
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
2563
|
+
|
|
2564
|
+
const size_type block = size_type(block_size - size_type(cur - *current_node));
|
|
2565
|
+
size_type cnt = n < block ? n: block;
|
|
2566
|
+
dest = ::boost::container::move_n(boost::movelib::to_raw_pointer(cur), cnt, dest);
|
|
2567
|
+
n = size_type(n - cnt);
|
|
2568
|
+
|
|
2569
|
+
while (n) {
|
|
2570
|
+
++current_node;
|
|
2571
|
+
cnt = n < block_size ? n: block_size;
|
|
2572
|
+
dest = ::boost::container::move_n(boost::movelib::to_raw_pointer(*current_node), cnt, dest);
|
|
2573
|
+
n = size_type(n - cnt);
|
|
2574
|
+
}
|
|
2575
|
+
return dest;
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
static iterator priv_segmented_move_backward_n(iterator last, size_type n, iterator dest_last)
|
|
2579
|
+
{
|
|
2580
|
+
index_pointer current_node = last.get_node();
|
|
2581
|
+
BOOST_ASSERT(current_node != index_pointer());
|
|
2582
|
+
|
|
2583
|
+
const pointer cur = last.get_cur();
|
|
2584
|
+
const size_type block = size_type(cur - *current_node);
|
|
2585
|
+
size_type cnt = n < block ? n: block;
|
|
2586
|
+
dest_last = ::boost::container::move_backward_n(boost::movelib::to_raw_pointer(cur), cnt, dest_last);
|
|
2587
|
+
n = size_type(n - cnt);
|
|
2588
|
+
|
|
2589
|
+
BOOST_CONSTEXPR_OR_CONST size_type block_size = get_block_size();
|
|
2590
|
+
|
|
2591
|
+
while (n) {
|
|
2592
|
+
--current_node;
|
|
2593
|
+
cnt = n < block_size ? n: block_size;
|
|
2594
|
+
dest_last = ::boost::container::move_backward_n(boost::movelib::to_raw_pointer(*current_node + difference_type(block_size)), cnt, dest_last);
|
|
2595
|
+
n = size_type(n - cnt);
|
|
2596
|
+
}
|
|
2597
|
+
return dest_last;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
template <class InsertProxy>
|
|
2601
|
+
iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
|
|
2602
|
+
{
|
|
2603
|
+
this->priv_reserve_elements_at_back(n);
|
|
2604
|
+
const iterator old_finish = this->prot_finish();
|
|
2605
|
+
this->priv_insert_segmented_uninitialized_copy_n_and_update(old_finish, n, proxy);
|
|
2606
|
+
this->prot_inc_finish(n);
|
|
2607
|
+
return old_finish;
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
template <class InsertProxy>
|
|
2611
|
+
iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
|
|
2612
|
+
{
|
|
2613
|
+
BOOST_ASSERT(!is_single_ended);
|
|
2614
|
+
this->priv_reserve_elements_at_front(n);
|
|
2615
|
+
const iterator old_start = this->prot_start();
|
|
2616
|
+
const iterator new_start = old_start - difference_type(n);
|
|
2617
|
+
this->priv_insert_segmented_uninitialized_copy_n_and_update(new_start, n, proxy);
|
|
2618
|
+
this->members_.dec_start(n);
|
|
2619
|
+
return new_start;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
// Precondition: this->prot_start() and this->prot_finish() have already been initialized,
|
|
2623
|
+
// but none of the deque's elements have yet been constructed.
|
|
2624
|
+
void priv_fill_initialize(size_type n, const value_type& value)
|
|
2625
|
+
{
|
|
2626
|
+
dtl::insert_n_copies_proxy<ValAllocator> proxy(value);
|
|
2627
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
template <class InIt>
|
|
2631
|
+
void priv_range_initialize(InIt first, InIt last, typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type* =0)
|
|
2632
|
+
{
|
|
2633
|
+
BOOST_CONTAINER_TRY {
|
|
2634
|
+
for ( ; first != last; ++first)
|
|
2635
|
+
this->emplace_back(*first);
|
|
2636
|
+
}
|
|
2637
|
+
BOOST_CONTAINER_CATCH(...){
|
|
2638
|
+
this->clear();
|
|
2639
|
+
BOOST_CONTAINER_RETHROW
|
|
2640
|
+
}
|
|
2641
|
+
BOOST_CONTAINER_CATCH_END
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
template <class FwdIt>
|
|
2645
|
+
void priv_range_initialize(FwdIt first, FwdIt last, typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type* =0)
|
|
2646
|
+
{
|
|
2647
|
+
typedef typename iter_size<FwdIt>::type it_size_type;
|
|
2648
|
+
const it_size_type sz = boost::container::iterator_udistance(first, last);
|
|
2649
|
+
if (BOOST_UNLIKELY(sz > size_type(-1))){
|
|
2650
|
+
boost::container::throw_length_error("vector::insert, FwdIt's max length reached");
|
|
2651
|
+
}
|
|
2652
|
+
const size_type n = static_cast<size_type>(sz);
|
|
2653
|
+
this->prot_initialize_map_and_nodes(n);
|
|
2654
|
+
|
|
2655
|
+
dtl::insert_range_proxy<ValAllocator, FwdIt> proxy(first);
|
|
2656
|
+
this->priv_segmented_proxy_uninitialized_copy_n_and_update(this->begin(), n, proxy);
|
|
2657
|
+
}
|
|
2658
|
+
|
|
2659
|
+
// Called only if this->prot_finish_cur() == this->prot_finish().get_first().
|
|
2660
|
+
void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
|
|
2661
|
+
{
|
|
2662
|
+
index_pointer ip = this->prot_finish_node();
|
|
2663
|
+
this->prot_deallocate_node_if_not_reservable(*ip);
|
|
2664
|
+
this->prot_dec_finish();
|
|
2665
|
+
--ip;
|
|
2666
|
+
allocator_traits_type::destroy
|
|
2667
|
+
( this->alloc()
|
|
2668
|
+
, boost::movelib::to_raw_pointer(this->prot_node_last(ip))
|
|
2669
|
+
);
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
// Called only if this->prot_start_cur() == this->prot_start().get_last() - 1. Note that
|
|
2673
|
+
// if the deque has at least one element (a precondition for this member
|
|
2674
|
+
// function), and if this->prot_start_cur() == this->prot_start().get_last(), then the deque
|
|
2675
|
+
// must have at least two nodes.
|
|
2676
|
+
void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
|
|
2677
|
+
{
|
|
2678
|
+
BOOST_ASSERT(!is_single_ended);
|
|
2679
|
+
const index_pointer ip = this->prot_start_node();
|
|
2680
|
+
allocator_traits_type::destroy
|
|
2681
|
+
( this->alloc()
|
|
2682
|
+
, boost::movelib::to_raw_pointer(this->prot_node_last(ip))
|
|
2683
|
+
);
|
|
2684
|
+
this->prot_deallocate_node_if_not_reservable(*ip);
|
|
2685
|
+
this->members_.inc_start();
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
void priv_reserve_elements_at_front(size_type n)
|
|
2689
|
+
{
|
|
2690
|
+
BOOST_ASSERT(!is_single_ended);
|
|
2691
|
+
const size_type vacancies = this->prot_front_free_capacity();
|
|
2692
|
+
typedef dtl::bool_<is_reservable> res_t;
|
|
2693
|
+
|
|
2694
|
+
if (n > vacancies){ //n == 0 handled in the else part
|
|
2695
|
+
if(this->members_.m_map){
|
|
2696
|
+
//front growth is inherently double-ended
|
|
2697
|
+
this->prot_reallocate_map_and_nodes(res_t(), dtl::bool_<false>(), size_type(n - vacancies), true);
|
|
2698
|
+
}
|
|
2699
|
+
else {
|
|
2700
|
+
this->prot_initialize_map_and_nodes(n);
|
|
2701
|
+
this->prot_reset_start_to_finish();
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
void priv_reserve_elements_at_back(size_type n)
|
|
2707
|
+
{
|
|
2708
|
+
const size_type vacancies = this->prot_back_free_capacity();
|
|
2709
|
+
typedef dtl::bool_<is_reservable> res_t;
|
|
2710
|
+
|
|
2711
|
+
if (n > vacancies){ //n == 0 handled in the else part
|
|
2712
|
+
if(this->members_.m_map){
|
|
2713
|
+
this->prot_reallocate_map_and_nodes(res_t(), dtl::bool_<is_single_ended>(), size_type(n - vacancies), false);
|
|
2714
|
+
}
|
|
2715
|
+
else{
|
|
2716
|
+
this->prot_initialize_map_and_nodes(n);
|
|
2717
|
+
this->prot_reset_finish_to_start();
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
};
|
|
2722
|
+
|
|
2723
|
+
}} //boost::container
|
|
2724
|
+
|
|
2725
|
+
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
2726
|
+
|
|
2727
|
+
namespace boost {
|
|
2728
|
+
|
|
2729
|
+
//!has_trivial_destructor_after_move<> == true_type
|
|
2730
|
+
//!specialization for optimizations
|
|
2731
|
+
template <class T, class Allocator, bool SingleEnded, class Options>
|
|
2732
|
+
struct has_trivial_destructor_after_move<boost::container::deque_impl<T, Allocator, SingleEnded, Options> >
|
|
2733
|
+
{
|
|
2734
|
+
typedef typename boost::container::deque_impl<T, Allocator, SingleEnded, Options>::allocator_type allocator_type;
|
|
2735
|
+
typedef typename boost::container::allocator_traits<allocator_type>::pointer pointer;
|
|
2736
|
+
BOOST_STATIC_CONSTEXPR bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
|
|
2737
|
+
::boost::has_trivial_destructor_after_move<pointer>::value;
|
|
2738
|
+
};
|
|
2739
|
+
|
|
2740
|
+
} //boost
|
|
2741
|
+
|
|
2742
|
+
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
2743
|
+
|
|
2744
|
+
#endif //BOOST_CONTAINER_DETAIL_DEQUE_IMPL_HPP
|