|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r51964 - in trunk: boost/interprocess boost/interprocess/allocators boost/interprocess/allocators/detail boost/interprocess/containers boost/interprocess/containers/container boost/interprocess/containers/container/detail boost/interprocess/containers/detail boost/interprocess/detail boost/interprocess/indexes boost/interprocess/mem_algo boost/interprocess/mem_algo/detail boost/interprocess/smart_ptr boost/interprocess/smart_ptr/detail boost/interprocess/sync boost/interprocess/sync/emulation boost/interprocess/sync/posix boost/intrusive boost/intrusive/detail libs/interprocess/doc libs/interprocess/example libs/interprocess/proj libs/interprocess/proj/vc7ide libs/interprocess/test libs/intrusive/doc libs/intrusive/example libs/intrusive/proj/vc7ide libs/intrusive/proj/vc7ide/any_test libs/intrusive/proj/vc7ide/custom_bucket_traits libs/intrusive/proj/vc7ide/default_hook libs/intrusive/proj/vc7ide/external_value_traits libs/intrusive/proj/vc7ide/list libs/intrusive/proj/vc7ide/make_functions libs/intrusive/proj/vc7ide/stateful_value_traits libs/intrusive/proj/vc7ide/virtual_base libs/intrusive/test
From: igaztanaga_at_[hidden]
Date: 2009-03-24 17:53:00
Author: igaztanaga
Date: 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
New Revision: 51964
URL: http://svn.boost.org/trac/boost/changeset/51964
Log:
Changes for Boost.1.39
Added:
trunk/boost/interprocess/containers/allocation_type.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/
trunk/boost/interprocess/containers/container/containers_fwd.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/deque.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/
trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/algorithms.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/allocation_type.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/config_begin.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/config_end.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/destroyers.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/flat_tree.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/iterators.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/mpl.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/pair.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/preprocessor.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/tree.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/type_traits.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/utilities.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/value_init.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/version_type.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/detail/workaround.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/flat_map.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/flat_set.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/list.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/map.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/set.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/slist.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/stable_vector.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/string.hpp (contents, props changed)
trunk/boost/interprocess/containers/container/vector.hpp (contents, props changed)
trunk/boost/interprocess/containers/pair.hpp (contents, props changed)
trunk/boost/interprocess/containers/stable_vector.hpp (contents, props changed)
trunk/boost/interprocess/containers/version_type.hpp (contents, props changed)
trunk/boost/interprocess/detail/transform_iterator.hpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_conditionA.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_conditionB.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_mutexA.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_mutexB.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_semaphoreA.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_semaphoreB.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexA.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexB.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_message_queueA.cpp (contents, props changed)
trunk/libs/interprocess/example/comp_doc_message_queueB.cpp (contents, props changed)
trunk/libs/interprocess/example/doc_ipc_message.cpp (contents, props changed)
trunk/libs/interprocess/example/doc_named_alloc.cpp (contents, props changed)
trunk/libs/interprocess/example/doc_spawn_vector.cpp (contents, props changed)
trunk/libs/interprocess/proj/vc7ide/doc_ipc_message.vcproj (contents, props changed)
trunk/libs/interprocess/proj/vc7ide/doc_named_alloc.vcproj (contents, props changed)
trunk/libs/interprocess/proj/vc7ide/doc_spawn_vector.vcproj (contents, props changed)
trunk/libs/interprocess/proj/vc7ide/stable_vector_test.vcproj (contents, props changed)
trunk/libs/interprocess/test/stable_vector_test.cpp (contents, props changed)
Removed:
trunk/boost/interprocess/allocators/allocation_type.hpp
trunk/boost/interprocess/containers/detail/flat_tree.hpp
trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp
trunk/boost/interprocess/containers/detail/tree.hpp
trunk/boost/interprocess/detail/advanced_insert_int.hpp
trunk/boost/interprocess/detail/algorithms.hpp
trunk/boost/interprocess/detail/iterators.hpp
trunk/boost/interprocess/detail/move_iterator.hpp
trunk/boost/interprocess/detail/version_type.hpp
trunk/libs/interprocess/example/doc_anonymous_conditionA.cpp
trunk/libs/interprocess/example/doc_anonymous_conditionB.cpp
trunk/libs/interprocess/example/doc_anonymous_mutexA.cpp
trunk/libs/interprocess/example/doc_anonymous_mutexB.cpp
trunk/libs/interprocess/example/doc_anonymous_semaphoreA.cpp
trunk/libs/interprocess/example/doc_anonymous_semaphoreB.cpp
trunk/libs/interprocess/example/doc_anonymous_upgradable_mutexA.cpp
trunk/libs/interprocess/example/doc_anonymous_upgradable_mutexB.cpp
trunk/libs/interprocess/example/doc_contA.cpp
trunk/libs/interprocess/example/doc_contB.cpp
trunk/libs/interprocess/example/doc_file_mapping2.cpp
trunk/libs/interprocess/example/doc_ipc_messageA.cpp
trunk/libs/interprocess/example/doc_ipc_messageB.cpp
trunk/libs/interprocess/example/doc_message_queueA.cpp
trunk/libs/interprocess/example/doc_message_queueB.cpp
trunk/libs/interprocess/example/doc_named_allocA.cpp
trunk/libs/interprocess/example/doc_named_allocB.cpp
trunk/libs/interprocess/example/doc_shared_memory2.cpp
trunk/libs/interprocess/example/doc_windows_shared_memory2.cpp
trunk/libs/interprocess/proj/vc7ide/doc_file_mapping2.vcproj
trunk/libs/interprocess/proj/vc7ide/doc_ipc_messageA.vcproj
trunk/libs/interprocess/proj/vc7ide/doc_ipc_messageB.vcproj
trunk/libs/interprocess/proj/vc7ide/doc_named_allocA.vcproj
trunk/libs/interprocess/proj/vc7ide/doc_named_allocB.vcproj
Text files modified:
trunk/boost/interprocess/allocators/adaptive_pool.hpp | 30
trunk/boost/interprocess/allocators/allocator.hpp | 56
trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp | 16
trunk/boost/interprocess/allocators/cached_node_allocator.hpp | 16
trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 61
trunk/boost/interprocess/allocators/detail/allocator_common.hpp | 200 +-
trunk/boost/interprocess/allocators/detail/node_pool.hpp | 56
trunk/boost/interprocess/allocators/node_allocator.hpp | 30
trunk/boost/interprocess/allocators/private_adaptive_pool.hpp | 30
trunk/boost/interprocess/allocators/private_node_allocator.hpp | 30
trunk/boost/interprocess/anonymous_shared_memory.hpp | 22
trunk/boost/interprocess/containers/deque.hpp | 1518 ------------------------
trunk/boost/interprocess/containers/flat_map.hpp | 1431 ----------------------
trunk/boost/interprocess/containers/flat_set.hpp | 1234 -------------------
trunk/boost/interprocess/containers/list.hpp | 1451 -----------------------
trunk/boost/interprocess/containers/map.hpp | 1303 --------------------
trunk/boost/interprocess/containers/set.hpp | 1176 ------------------
trunk/boost/interprocess/containers/slist.hpp | 1631 --------------------------
trunk/boost/interprocess/containers/string.hpp | 2485 ---------------------------------------
trunk/boost/interprocess/containers/vector.hpp | 1978 -------------------------------
trunk/boost/interprocess/detail/atomic.hpp | 2
trunk/boost/interprocess/detail/file_wrapper.hpp | 27
trunk/boost/interprocess/detail/managed_memory_impl.hpp | 16
trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp | 8
trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp | 43
trunk/boost/interprocess/detail/move.hpp | 780 ++++++++++-
trunk/boost/interprocess/detail/mpl.hpp | 6
trunk/boost/interprocess/detail/named_proxy.hpp | 8
trunk/boost/interprocess/detail/os_file_functions.hpp | 119 +
trunk/boost/interprocess/detail/os_thread_functions.hpp | 51
trunk/boost/interprocess/detail/preprocessor.hpp | 32
trunk/boost/interprocess/detail/segment_manager_helper.hpp | 35
trunk/boost/interprocess/detail/tmp_dir_helpers.hpp | 79 +
trunk/boost/interprocess/detail/type_traits.hpp | 4
trunk/boost/interprocess/detail/utilities.hpp | 727 -----------
trunk/boost/interprocess/detail/win32_api.hpp | 469 +++++++
trunk/boost/interprocess/detail/workaround.hpp | 47
trunk/boost/interprocess/errors.hpp | 22
trunk/boost/interprocess/file_mapping.hpp | 65
trunk/boost/interprocess/indexes/iunordered_set_index.hpp | 6
trunk/boost/interprocess/interprocess_fwd.hpp | 130 -
trunk/boost/interprocess/managed_external_buffer.hpp | 47
trunk/boost/interprocess/managed_heap_memory.hpp | 49
trunk/boost/interprocess/managed_mapped_file.hpp | 47
trunk/boost/interprocess/managed_shared_memory.hpp | 52
trunk/boost/interprocess/managed_windows_shared_memory.hpp | 45
trunk/boost/interprocess/mapped_region.hpp | 166 +-
trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp | 674 ++++++++--
trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp | 42
trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 106
trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 134 -
trunk/boost/interprocess/offset_ptr.hpp | 6
trunk/boost/interprocess/segment_manager.hpp | 70
trunk/boost/interprocess/shared_memory_object.hpp | 59
trunk/boost/interprocess/smart_ptr/deleter.hpp | 5
trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp | 17
trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp | 39
trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp | 3
trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp | 3
trunk/boost/interprocess/smart_ptr/shared_ptr.hpp | 51
trunk/boost/interprocess/smart_ptr/unique_ptr.hpp | 97 -
trunk/boost/interprocess/smart_ptr/weak_ptr.hpp | 3
trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp | 15
trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp | 37
trunk/boost/interprocess/sync/file_lock.hpp | 38
trunk/boost/interprocess/sync/interprocess_barrier.hpp | 4
trunk/boost/interprocess/sync/interprocess_condition.hpp | 4
trunk/boost/interprocess/sync/interprocess_mutex.hpp | 6
trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 8
trunk/boost/interprocess/sync/interprocess_semaphore.hpp | 6
trunk/boost/interprocess/sync/named_condition.hpp | 14
trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 2
trunk/boost/interprocess/sync/scoped_lock.hpp | 144 -
trunk/boost/interprocess/sync/sharable_lock.hpp | 99 -
trunk/boost/interprocess/sync/upgradable_lock.hpp | 103 -
trunk/boost/interprocess/windows_shared_memory.hpp | 32
trunk/boost/intrusive/detail/ebo_functor_holder.hpp | 10
trunk/boost/intrusive/detail/parent_from_member.hpp | 3
trunk/boost/intrusive/detail/tree_node.hpp | 8
trunk/boost/intrusive/hashtable.hpp | 4
trunk/boost/intrusive/list.hpp | 34
trunk/boost/intrusive/rbtree.hpp | 8
trunk/boost/intrusive/slist.hpp | 83
trunk/libs/interprocess/doc/Jamfile.v2 | 9
trunk/libs/interprocess/doc/interprocess.qbk | 185 +-
trunk/libs/interprocess/example/Jamfile.v2 | 13
trunk/libs/interprocess/example/doc_adaptive_pool.cpp | 76
trunk/libs/interprocess/example/doc_allocator.cpp | 7
trunk/libs/interprocess/example/doc_bufferstream.cpp | 119
trunk/libs/interprocess/example/doc_cached_adaptive_pool.cpp | 95
trunk/libs/interprocess/example/doc_cached_node_allocator.cpp | 95
trunk/libs/interprocess/example/doc_complex_map.cpp | 39
trunk/libs/interprocess/example/doc_cont.cpp | 83
trunk/libs/interprocess/example/doc_file_mapping.cpp | 81
trunk/libs/interprocess/example/doc_intrusive.cpp | 69
trunk/libs/interprocess/example/doc_managed_aligned_allocation.cpp | 65
trunk/libs/interprocess/example/doc_managed_allocation_command.cpp | 124 -
trunk/libs/interprocess/example/doc_managed_construction_info.cpp | 66
trunk/libs/interprocess/example/doc_managed_copy_on_write.cpp | 5
trunk/libs/interprocess/example/doc_managed_external_buffer.cpp | 4
trunk/libs/interprocess/example/doc_managed_grow.cpp | 81
trunk/libs/interprocess/example/doc_managed_mapped_file.cpp | 86
trunk/libs/interprocess/example/doc_managed_multiple_allocation.cpp | 94
trunk/libs/interprocess/example/doc_managed_raw_allocation.cpp | 41
trunk/libs/interprocess/example/doc_map.cpp | 91
trunk/libs/interprocess/example/doc_move_containers.cpp | 97
trunk/libs/interprocess/example/doc_multi_index.cpp | 39
trunk/libs/interprocess/example/doc_named_mutex.cpp | 3
trunk/libs/interprocess/example/doc_node_allocator.cpp | 76
trunk/libs/interprocess/example/doc_offset_ptr.cpp | 70
trunk/libs/interprocess/example/doc_private_adaptive_pool.cpp | 68
trunk/libs/interprocess/example/doc_private_node_allocator.cpp | 68
trunk/libs/interprocess/example/doc_scoped_ptr.cpp | 93
trunk/libs/interprocess/example/doc_shared_memory.cpp | 39
trunk/libs/interprocess/example/doc_shared_ptr.cpp | 5
trunk/libs/interprocess/example/doc_shared_ptr_explicit.cpp | 10
trunk/libs/interprocess/example/doc_unique_ptr.cpp | 12
trunk/libs/interprocess/example/doc_unordered_map.cpp | 75
trunk/libs/interprocess/example/doc_vectorstream.cpp | 148 +-
trunk/libs/interprocess/example/doc_where_allocate.cpp | 77
trunk/libs/interprocess/example/doc_windows_shared_memory.cpp | 50
trunk/libs/interprocess/proj/to-do.txt | 26
trunk/libs/interprocess/proj/vc7ide/Interprocess.sln | 122 -
trunk/libs/interprocess/proj/vc7ide/adaptive_node_pool_test.vcproj | 1
trunk/libs/interprocess/proj/vc7ide/doc_adaptive_pool.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_allocator.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionA.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexA.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreA.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_shared_memory.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexA.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_bufferstream.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_cached_adaptive_pool.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_cached_node_allocator.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_cont.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_contB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_file_mapping.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_intrusive.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_aligned_allocation.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_allocation_command.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_construction_info.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_grow.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_heap_memory.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_mapped_file.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_multiple_allocation.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_managed_raw_allocation.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_map.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_message_queueA.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_message_queueB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_move_containers.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_named_conditionA.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_named_conditionB.vcproj | 7
trunk/libs/interprocess/proj/vc7ide/doc_named_mutex.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_node_allocator.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_offset_ptr.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_private_adaptive_pool.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_private_node_allocator.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_scoped_ptr.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_shared_memory.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr_explicit.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_unique_ptr.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_vectorstream.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_where_allocate.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory.vcproj | 5
trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory2.vcproj | 11
trunk/libs/interprocess/proj/vc7ide/interprocesslib.vcproj | 43
trunk/libs/interprocess/proj/vc7ide/shared_memory_mappable_test.vcproj | 2
trunk/libs/interprocess/proj/vc7ide/string_test.vcproj | 1
trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_mapping_test.vcproj | 8
trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_test.vcproj | 4
trunk/libs/interprocess/test/adaptive_node_pool_test.cpp | 1
trunk/libs/interprocess/test/allocator_v1.hpp | 14
trunk/libs/interprocess/test/check_equal_containers.hpp | 6
trunk/libs/interprocess/test/data_test.cpp | 6
trunk/libs/interprocess/test/deque_test.cpp | 44
trunk/libs/interprocess/test/dummy_test_allocator.hpp | 8
trunk/libs/interprocess/test/emplace_test.hpp | 23
trunk/libs/interprocess/test/expand_bwd_test_allocator.hpp | 10
trunk/libs/interprocess/test/file_lock_test.cpp | 12
trunk/libs/interprocess/test/file_mapping_test.cpp | 17
trunk/libs/interprocess/test/flat_tree_test.cpp | 46
trunk/libs/interprocess/test/get_process_id_name.hpp | 4
trunk/libs/interprocess/test/list_test.cpp | 5
trunk/libs/interprocess/test/list_test.hpp | 18
trunk/libs/interprocess/test/managed_mapped_file_test.cpp | 11
trunk/libs/interprocess/test/managed_shared_memory_test.cpp | 5
trunk/libs/interprocess/test/managed_windows_shared_memory_test.cpp | 7
trunk/libs/interprocess/test/map_test.hpp | 415 ++++--
trunk/libs/interprocess/test/mapped_file_test.cpp | 11
trunk/libs/interprocess/test/memory_algorithm_test_template.hpp | 66
trunk/libs/interprocess/test/movable_int.hpp | 56
trunk/libs/interprocess/test/multi_index_test.cpp | 56
trunk/libs/interprocess/test/set_test.hpp | 102
trunk/libs/interprocess/test/shared_memory_mapping_test.cpp | 13
trunk/libs/interprocess/test/shared_memory_test.cpp | 11
trunk/libs/interprocess/test/shared_ptr_test.cpp | 8
trunk/libs/interprocess/test/slist_test.cpp | 9
trunk/libs/interprocess/test/string_test.cpp | 4
trunk/libs/interprocess/test/tree_test.cpp | 45
trunk/libs/interprocess/test/unique_ptr_test.cpp | 29
trunk/libs/interprocess/test/upgradable_mutex_test.cpp | 70
trunk/libs/interprocess/test/user_buffer_test.cpp | 22
trunk/libs/interprocess/test/vector_test.cpp | 22
trunk/libs/interprocess/test/vector_test.hpp | 44
trunk/libs/interprocess/test/windows_shared_memory_mapping_test.cpp | 2
trunk/libs/interprocess/test/windows_shared_memory_test.cpp | 14
trunk/libs/intrusive/doc/intrusive.qbk | 11
trunk/libs/intrusive/example/doc_any_hook.cpp | 2
trunk/libs/intrusive/proj/vc7ide/any_test/any_test.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/custom_bucket_traits/custom_bucket_traits.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/default_hook/default_hook.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/external_value_traits/external_value_traits.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/list/list.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/make_functions/make_functions.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/stateful_value_traits/stateful_value_traits.vcproj | 2
trunk/libs/intrusive/proj/vc7ide/to-do.txt | 2
trunk/libs/intrusive/proj/vc7ide/virtual_base/virtual_base.vcproj | 2
trunk/libs/intrusive/test/slist_test.cpp | 22
trunk/libs/intrusive/test/unordered_multiset_test.cpp | 9
trunk/libs/intrusive/test/unordered_set_test.cpp | 2
225 files changed, 5014 insertions(+), 19020 deletions(-)
Modified: trunk/boost/interprocess/allocators/adaptive_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/adaptive_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/adaptive_pool.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,6 +18,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
@@ -80,9 +82,9 @@
public:
//-------
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
@@ -92,13 +94,9 @@
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef detail::version_type<adaptive_pool_base, Version> version;
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef typename SegmentManager::
- multiallocation_chain multiallocation_chain;
+ typedef boost::interprocess::version_type<adaptive_pool_base, Version> version;
+ typedef detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
//!Obtains adaptive_pool_base from
//!adaptive_pool_base
@@ -266,7 +264,7 @@
typedef detail::adaptive_pool_base
< 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
public:
- typedef detail::version_type<adaptive_pool, 2> version;
+ typedef boost::interprocess::version_type<adaptive_pool, 2> version;
template<class T2>
struct rebind
@@ -388,7 +386,7 @@
size_type size(const pointer &p) const;
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -399,12 +397,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -412,7 +410,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -425,7 +423,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements);
+ multiallocation_chain allocate_individual(std::size_t num_elements);
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -438,7 +436,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it);
+ void deallocate_individual(multiallocation_chain it);
#endif
};
Deleted: trunk/boost/interprocess/allocators/allocation_type.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/allocation_type.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,55 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_TYPE_COMMAND_HPP
-#define BOOST_INTERPROCESS_TYPE_COMMAND_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-namespace boost {
-namespace interprocess {
-
-/// @cond
-enum allocation_type_v
-{
- // constants for allocation commands
- allocate_new_v = 0x01,
- expand_fwd_v = 0x02,
- expand_bwd_v = 0x04,
-// expand_both = expand_fwd | expand_bwd,
-// expand_or_new = allocate_new | expand_both,
- shrink_in_place_v = 0x08,
- nothrow_allocation_v = 0x10,
- zero_memory_v = 0x20,
- try_shrink_in_place_v = 0x40
-};
-
-typedef int allocation_type;
-/// @endcond
-static const allocation_type allocate_new = (allocation_type)allocate_new_v;
-static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
-static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
-static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
-static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
-static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
-static const allocation_type zero_memory = (allocation_type)zero_memory_v;
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_TYPE_COMMAND_HPP
-
Modified: trunk/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/allocator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,15 +18,17 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
+#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
#include <memory>
#include <algorithm>
@@ -64,11 +66,11 @@
//Typedef to const void pointer
typedef typename
- detail::pointer_to_other
+ boost::pointer_to_other
<aux_pointer_t, const void>::type cvoid_ptr;
//Pointer to the allocator
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<cvoid_ptr, segment_manager>::type alloc_ptr_t;
//Not assignable from related allocator
@@ -84,9 +86,9 @@
public:
typedef T value_type;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<cvoid_ptr, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<pointer, const T>::type const_pointer;
typedef typename detail::add_reference
<value_type>::type reference;
@@ -95,20 +97,13 @@
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef detail::version_type<allocator, 2> version;
+ typedef boost::interprocess::version_type<allocator, 2> version;
/// @cond
//Experimental. Don't use.
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef detail::multiallocation_chain_adaptor
- <typename SegmentManager::
- multiallocation_chain
- , T> multiallocation_chain;
-
+ typedef boost::interprocess::detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
/// @endcond
//!Obtains an allocator that allocates
@@ -174,7 +169,7 @@
}
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
@@ -189,19 +184,19 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements)
+ multiallocation_chain allocate_many
+ (size_type elem_size, std::size_t num_elements)
{
- return multiallocation_iterator
- (mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
+ return multiallocation_chain(mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
}
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements)
+ multiallocation_chain allocate_many
+ (const size_type *elem_sizes, size_type n_elements)
{
- return multiallocation_iterator
- (mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T)));
+ multiallocation_chain(mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T)));
}
//!Allocates many elements of size elem_size in a contiguous block
@@ -210,8 +205,10 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it)
- { return mp_mngr->deallocate_many(it.base()); }
+ void deallocate_many(multiallocation_chain chain)
+ {
+ return mp_mngr->deallocate_many(chain.extract_multiallocation_chain());
+ }
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -225,7 +222,8 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements)
+ multiallocation_chain allocate_individual
+ (std::size_t num_elements)
{ return this->allocate_many(1, num_elements); }
//!Deallocates memory previously allocated with allocate_one().
@@ -240,8 +238,8 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it)
- { return this->deallocate_many(it); }
+ void deallocate_individual(multiallocation_chain chain)
+ { return this->deallocate_many(boost::interprocess::move(chain)); }
//!Returns address of mutable object.
//!Never throws
Modified: trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -23,7 +23,7 @@
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/allocators/detail/node_tools.hpp>
#include <cstddef>
@@ -143,7 +143,7 @@
, 2> base_t;
public:
- typedef detail::version_type<cached_adaptive_pool, 2> version;
+ typedef boost::interprocess::version_type<cached_adaptive_pool, 2> version;
template<class T2>
struct rebind
@@ -267,7 +267,7 @@
size_type size(const pointer &p) const;
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -278,12 +278,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -291,7 +291,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -304,7 +304,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements);
+ multiallocation_chain allocate_individual(std::size_t num_elements);
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -317,7 +317,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it);
+ void deallocate_individual(multiallocation_chain chain);
//!Sets the new max cached nodes value. This can provoke deallocations
//!if "newmax" is less than current cached nodes. Never throws
void set_max_cached_nodes(std::size_t newmax);
Modified: trunk/boost/interprocess/allocators/cached_node_allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/cached_node_allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/cached_node_allocator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -23,7 +23,7 @@
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/allocators/detail/node_tools.hpp>
#include <cstddef>
@@ -115,7 +115,7 @@
, 2> base_t;
public:
- typedef detail::version_type<cached_node_allocator, 2> version;
+ typedef boost::interprocess::version_type<cached_node_allocator, 2> version;
template<class T2>
struct rebind
@@ -238,7 +238,7 @@
size_type size(const pointer &p) const;
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -249,12 +249,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -262,7 +262,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -275,7 +275,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements);
+ multiallocation_chain allocate_individual(std::size_t num_elements);
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -288,7 +288,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it);
+ void deallocate_individual(multiallocation_chain it);
//!Sets the new max cached nodes value. This can provoke deallocations
//!if "newmax" is less than current cached nodes. Never throws
void set_max_cached_nodes(std::size_t newmax);
Modified: trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,6 +17,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -27,6 +28,7 @@
#include <boost/intrusive/slist.hpp>
#include <boost/math/common_factor_ct.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/interprocess/allocators/detail/node_tools.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <cstddef>
@@ -53,7 +55,6 @@
public:
typedef typename node_slist<void_pointer>::node_t node_t;
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
- typedef typename SegmentManagerBase::multiallocation_iterator multiallocation_iterator;
typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
private:
@@ -200,8 +201,9 @@
//!Deallocates an array pointed by ptr. Never throws
void deallocate_node(void *pElem)
{
- this->priv_reinsert_nodes_in_block
- (multiallocation_iterator::create_simple_range(pElem));
+ multiallocation_chain chain;
+ chain.push_front(void_pointer(pElem));
+ this->priv_reinsert_nodes_in_block(chain, 1);
//Update free block count
if(m_totally_free_blocks > m_max_free_blocks){
this->priv_deallocate_free_blocks(m_max_free_blocks);
@@ -209,13 +211,14 @@
priv_invariants();
}
- //!Allocates a singly linked list of n nodes ending in null pointer.
- //!can throw boost::interprocess::bad_alloc
- void allocate_nodes(multiallocation_chain &nodes, const std::size_t n)
+ //!Allocates n nodes.
+ //!Can throw boost::interprocess::bad_alloc
+ multiallocation_chain allocate_nodes(const std::size_t n)
{
+ multiallocation_chain chain;
+ std::size_t i = 0;
try{
priv_invariants();
- std::size_t i = 0;
while(i != n){
//If there are no free nodes we allocate all needed blocks
if (m_block_multiset.empty()){
@@ -230,9 +233,9 @@
for(std::size_t j = 0; j != num_elems; ++j){
void *new_node = &free_nodes.front();
free_nodes.pop_front();
- nodes.push_back(new_node);
+ chain.push_back(new_node);
}
-
+
if(free_nodes.empty()){
m_block_multiset.erase(m_block_multiset.begin());
}
@@ -240,41 +243,23 @@
}
}
catch(...){
- this->deallocate_nodes(nodes, nodes.size());
+ this->deallocate_nodes(chain, i);
throw;
}
priv_invariants();
- }
-
- //!Allocates n nodes, pointed by the multiallocation_iterator.
- //!Can throw boost::interprocess::bad_alloc
- multiallocation_iterator allocate_nodes(const std::size_t n)
- {
- multiallocation_chain chain;
- this->allocate_nodes(chain, n);
- return chain.get_it();
+ return boost::interprocess::move(chain);
}
//!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain &nodes)
+ void deallocate_nodes(multiallocation_chain nodes)
{
- this->deallocate_nodes(nodes.get_it());
- nodes.reset();
+ return deallocate_nodes(nodes, nodes.size());
}
//!Deallocates the first n nodes of a linked list of nodes. Never throws
void deallocate_nodes(multiallocation_chain &nodes, std::size_t n)
{
- assert(nodes.size() >= n);
- for(std::size_t i = 0; i < n; ++i){
- this->deallocate_node(nodes.pop_front());
- }
- }
-
- //!Deallocates the nodes pointed by the multiallocation iterator. Never throws
- void deallocate_nodes(multiallocation_iterator it)
- {
- this->priv_reinsert_nodes_in_block(it);
+ this->priv_reinsert_nodes_in_block(nodes, n);
if(m_totally_free_blocks > m_max_free_blocks){
this->priv_deallocate_free_blocks(m_max_free_blocks);
}
@@ -331,13 +316,12 @@
}
}
- void priv_reinsert_nodes_in_block(multiallocation_iterator it)
+ void priv_reinsert_nodes_in_block(multiallocation_chain &chain, std::size_t n)
{
- multiallocation_iterator itend;
block_iterator block_it(m_block_multiset.end());
- while(it != itend){
- void *pElem = &*it;
- ++it;
+ while(n--){
+ void *pElem = detail::get_pointer(chain.front());
+ chain.pop_front();
priv_invariants();
block_info_t *block_info = this->priv_block_from_node(pElem);
assert(block_info->free_nodes.size() < m_real_num_node);
@@ -484,6 +468,7 @@
std::size_t num_free_nodes = 0;
for(; it != itend; ++it){
//Check for memory leak
+ std::size_t n = (std::size_t)it->free_nodes.size(); (void)n;
assert(it->free_nodes.size() == m_real_num_node);
++num_free_nodes;
}
@@ -565,7 +550,7 @@
}
private:
- typedef typename pointer_to_other
+ typedef typename boost::pointer_to_other
<void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
const std::size_t m_max_free_blocks;
Modified: trunk/boost/interprocess/allocators/detail/allocator_common.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/allocator_common.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/allocator_common.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -8,25 +8,63 @@
//
//////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOCATOR_COMMON_HPP
-#define BOOST_INTERPROCESS_DETAIL_NODE_ALLOCATOR_COMMON_HPP
+#ifndef BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP
+#define BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/segment_manager.hpp>
+
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/utilities.hpp> //pointer_to_other, get_pointer
+#include <boost/interprocess/detail/utilities.hpp> //get_pointer
#include <utility> //std::pair
#include <boost/utility/addressof.hpp> //boost::addressof
#include <boost/assert.hpp> //BOOST_ASSERT
#include <boost/interprocess/exceptions.hpp> //bad_alloc
#include <boost/interprocess/sync/scoped_lock.hpp> //scoped_lock
-#include <boost/interprocess/allocators/allocation_type.hpp> //allocation_type
+#include <boost/interprocess/containers/allocation_type.hpp> //boost::interprocess::allocation_type
+#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
+#include <boost/interprocess/detail/segment_manager_helper.hpp>
#include <algorithm> //std::swap
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
namespace boost {
namespace interprocess {
+
+template <class T>
+struct sizeof_value
+{
+ static const std::size_t value = sizeof(T);
+};
+
+template <>
+struct sizeof_value<void>
+{
+ static const std::size_t value = sizeof(void*);
+};
+
+template <>
+struct sizeof_value<const void>
+{
+ static const std::size_t value = sizeof(void*);
+};
+
+template <>
+struct sizeof_value<volatile void>
+{
+ static const std::size_t value = sizeof(void*);
+};
+
+template <>
+struct sizeof_value<const volatile void>
+{
+ static const std::size_t value = sizeof(void*);
+};
+
namespace detail {
//!Object function that creates the node allocator if it is not created and
@@ -41,7 +79,7 @@
{
//Find or create the node_pool_t
mp_node_pool = mp_segment_manager->template find_or_construct
- <NodePool>(unique_instance)(mp_segment_manager);
+ <NodePool>(boost::interprocess::unique_instance)(mp_segment_manager);
//If valid, increment link count
if(mp_node_pool != 0)
mp_node_pool->inc_ref_count();
@@ -78,7 +116,7 @@
if(mp_node_pool->dec_ref_count() != 0) return;
//Last link, let's destroy the segment_manager
- mp_node_pool->get_segment_manager()->template destroy<NodePool>(unique_instance);
+ mp_node_pool->get_segment_manager()->template destroy<NodePool>(boost::interprocess::unique_instance);
}
//!Constructor. Initializes function
@@ -106,16 +144,15 @@
class cache_impl
{
typedef typename NodePool::segment_manager::
- void_pointer void_pointer;
+ void_pointer void_pointer;
typedef typename pointer_to_other
- <void_pointer, NodePool>::type node_pool_ptr;
- typedef typename NodePool::multiallocation_chain multiallocation_chain;
- node_pool_ptr mp_node_pool;
- multiallocation_chain m_cached_nodes;
- std::size_t m_max_cached_nodes;
+ <void_pointer, NodePool>::type node_pool_ptr;
+ typedef typename NodePool::multiallocation_chain multiallocation_chain;
+ node_pool_ptr mp_node_pool;
+ multiallocation_chain m_cached_nodes;
+ std::size_t m_max_cached_nodes;
public:
- typedef typename NodePool::multiallocation_iterator multiallocation_iterator;
typedef typename NodePool::segment_manager segment_manager;
cache_impl(segment_manager *segment_mngr, std::size_t max_cached_nodes)
@@ -149,31 +186,34 @@
{
//If don't have any cached node, we have to get a new list of free nodes from the pool
if(m_cached_nodes.empty()){
- mp_node_pool->allocate_nodes(m_cached_nodes, m_max_cached_nodes/2);
+ m_cached_nodes = mp_node_pool->allocate_nodes(m_max_cached_nodes/2);
}
- return m_cached_nodes.pop_front();
+ void *ret = detail::get_pointer(m_cached_nodes.front());
+ m_cached_nodes.pop_front();
+ return ret;
}
- multiallocation_iterator cached_allocation(std::size_t n)
+ multiallocation_chain cached_allocation(std::size_t n)
{
multiallocation_chain chain;
- std::size_t count = n;
+ std::size_t count = n, allocated(0);
BOOST_TRY{
//If don't have any cached node, we have to get a new list of free nodes from the pool
while(!m_cached_nodes.empty() && count--){
- void *ret = m_cached_nodes.pop_front();
+ void *ret = detail::get_pointer(m_cached_nodes.front());
+ m_cached_nodes.pop_front();
chain.push_back(ret);
+ ++allocated;
}
- if(chain.size() != n){
- mp_node_pool->allocate_nodes(chain, n - chain.size());
+ if(allocated != n){
+ multiallocation_chain chain2(mp_node_pool->allocate_nodes(n - allocated));
+ chain.splice_after(chain.last(), chain2, chain2.before_begin(), chain2.last(), n - allocated);
}
- assert(chain.size() == n);
- chain.splice_back(m_cached_nodes);
- return multiallocation_iterator(chain.get_it());
+ return boost::interprocess::move(chain);
}
BOOST_CATCH(...){
- this->cached_deallocation(multiallocation_iterator(chain.get_it()));
+ this->cached_deallocation(boost::interprocess::move(chain));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -192,15 +232,9 @@
m_cached_nodes.push_front(ptr);
}
- void cached_deallocation(multiallocation_iterator it)
+ void cached_deallocation(multiallocation_chain chain)
{
- multiallocation_iterator itend;
-
- while(it != itend){
- void *addr = &*it;
- ++it;
- m_cached_nodes.push_front(addr);
- }
+ m_cached_nodes.splice_after(m_cached_nodes.before_begin(), chain);
//Check if cache is full
if(m_cached_nodes.size() >= m_max_cached_nodes){
@@ -225,7 +259,7 @@
void deallocate_all_cached_nodes()
{
if(m_cached_nodes.empty()) return;
- mp_node_pool->deallocate_nodes(m_cached_nodes);
+ mp_node_pool->deallocate_nodes(boost::interprocess::move(m_cached_nodes));
}
private:
@@ -257,9 +291,9 @@
typedef typename SegmentManager::void_pointer void_pointer;
public:
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
@@ -268,12 +302,9 @@
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef typename SegmentManager::
- multiallocation_chain multiallocation_chain;
+ typedef detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
+
public:
//!Returns maximum the number of objects the previously allocated memory
@@ -285,7 +316,7 @@
}
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
@@ -300,19 +331,17 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements)
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements)
{
- return multiallocation_iterator
- (this->derived()->get_segment_manager()->allocate_many(sizeof(T)*elem_size, num_elements));
+ return this->derived()->get_segment_manager()->allocate_many(sizeof(T)*elem_size, num_elements);
}
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements)
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements)
{
- return multiallocation_iterator
- (this->derived()->get_segment_manager()->allocate_many(elem_sizes, n_elements, sizeof(T)));
+ return this->derived()->get_segment_manager()->allocate_many(elem_sizes, n_elements, sizeof(T));
}
//!Allocates many elements of size elem_size in a contiguous block
@@ -321,8 +350,8 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it)
- { return this->derived()->get_segment_manager()->deallocate_many(it.base()); }
+ void deallocate_many(multiallocation_chain chain)
+ { return this->derived()->get_segment_manager()->deallocate_many(boost::interprocess::move(chain)); }
//!Returns the number of elements that could be
//!allocated. Never throws
@@ -369,13 +398,13 @@
{ return static_cast<Derived*>(this); }
typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const void>::type cvoid_pointer;
public:
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
@@ -384,12 +413,9 @@
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef typename SegmentManager::
- multiallocation_chain multiallocation_chain;
+ typedef detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
+
template <int Dummy>
struct node_pool
@@ -445,11 +471,11 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements)
+ multiallocation_chain allocate_individual(std::size_t num_elements)
{
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
- return multiallocation_iterator(pool->allocate_nodes(num_elements));
+ return multiallocation_chain(pool->allocate_nodes(num_elements));
}
//!Deallocates memory previously allocated with allocate_one().
@@ -468,8 +494,11 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it)
- { node_pool<0>::get(this->derived()->get_node_pool())->deallocate_nodes(it.base()); }
+ void deallocate_individual(multiallocation_chain chain)
+ {
+ node_pool<0>::get(this->derived()->get_node_pool())->deallocate_nodes
+ (chain.extract_multiallocation_chain());
+ }
//!Deallocates all free blocks of the pool
void deallocate_free_blocks()
@@ -497,11 +526,10 @@
typedef NodePool node_pool_t;
typedef typename NodePool::segment_manager segment_manager;
typedef typename segment_manager::void_pointer void_pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const void>::type cvoid_pointer;
typedef typename base_t::pointer pointer;
typedef typename base_t::size_type size_type;
- typedef typename base_t::multiallocation_iterator multiallocation_iterator;
typedef typename base_t::multiallocation_chain multiallocation_chain;
typedef typename base_t::value_type value_type;
@@ -587,8 +615,8 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements)
- { return multiallocation_iterator(this->m_cache.cached_allocation(num_elements)); }
+ multiallocation_chain allocate_individual(std::size_t num_elements)
+ { return multiallocation_chain(this->m_cache.cached_allocation(num_elements)); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -602,8 +630,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it)
- { m_cache.cached_deallocation(it.base()); }
+ void deallocate_individual(multiallocation_chain chain)
+ {
+ typename node_pool_t::multiallocation_chain mem
+ (chain.extract_multiallocation_chain());
+ m_cache.cached_deallocation(boost::interprocess::move(mem));
+ }
//!Deallocates all free blocks of the pool
void deallocate_free_blocks()
@@ -655,11 +687,10 @@
{
public:
//!Segment manager typedef
- typedef typename private_node_allocator_t::segment_manager segment_manager;
typedef typename private_node_allocator_t::
- multiallocation_iterator multiallocation_iterator;
+ segment_manager segment_manager;
typedef typename private_node_allocator_t::
- multiallocation_chain multiallocation_chain;
+ multiallocation_chain multiallocation_chain;
private:
typedef typename segment_manager::mutex_family::mutex_type mutex_type;
@@ -691,7 +722,7 @@
//-----------------------
private_node_allocator_t::deallocate_node(ptr);
}
-
+/*
//!Allocates a singly linked list of n nodes ending in null pointer.
//!can throw boost::interprocess::bad_alloc
void allocate_nodes(multiallocation_chain &nodes, std::size_t n)
@@ -701,10 +732,10 @@
//-----------------------
return private_node_allocator_t::allocate_nodes(nodes, n);
}
-
- //!Allocates n nodes, pointed by the multiallocation_iterator.
+*/
+ //!Allocates n nodes.
//!Can throw boost::interprocess::bad_alloc
- multiallocation_iterator allocate_nodes(const std::size_t n)
+ multiallocation_chain allocate_nodes(const std::size_t n)
{
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
@@ -721,22 +752,13 @@
private_node_allocator_t::deallocate_nodes(nodes, num);
}
- //!Deallocates a linked list of nodes ending in null pointer. Never throws
- void deallocate_nodes(multiallocation_chain &nodes)
- {
- //-----------------------
- boost::interprocess::scoped_lock<mutex_type> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_nodes(nodes);
- }
-
//!Deallocates the nodes pointed by the multiallocation iterator. Never throws
- void deallocate_nodes(multiallocation_iterator it)
+ void deallocate_nodes(multiallocation_chain chain)
{
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
- private_node_allocator_t::deallocate_nodes(it);
+ private_node_allocator_t::deallocate_nodes(boost::interprocess::move(chain));
}
//!Deallocates all the free blocks of memory. Never throws
@@ -814,4 +836,4 @@
#include <boost/interprocess/detail/config_end.hpp>
-#endif //#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOCATOR_COMMON_HPP
+#endif //#ifndef BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP
Modified: trunk/boost/interprocess/allocators/detail/node_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/node_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/node_pool.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,14 +18,17 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/math/common_factor_ct.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/exceptions.hpp>
-#include <boost/intrusive/slist.hpp>
-#include <boost/math/common_factor_ct.hpp>
#include <boost/interprocess/detail/math_functions.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/allocators/detail/node_tools.hpp>
+#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <cstddef>
#include <functional>
@@ -53,7 +56,6 @@
typedef typename node_slist<void_pointer>::slist_hook_t slist_hook_t;
typedef typename node_slist<void_pointer>::node_t node_t;
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
- typedef typename SegmentManagerBase::multiallocation_iterator multiallocation_iterator;
typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
private:
@@ -112,25 +114,9 @@
--m_allocated;
}
- //!Allocates a singly linked list of n nodes ending in null pointer and pushes them in the chain.
- //!can throw boost::interprocess::bad_alloc
- void allocate_nodes(multiallocation_chain &nodes, const std::size_t n)
- {
- std::size_t i = 0;
- try{
- for(; i < n; ++i){
- nodes.push_front(this->allocate_node());
- }
- }
- catch(...){
- this->deallocate_nodes(nodes, i);
- throw;
- }
- }
-
//!Allocates a singly linked list of n nodes ending in null pointer
//!can throw boost::interprocess::bad_alloc
- multiallocation_iterator allocate_nodes(const std::size_t n)
+ multiallocation_chain allocate_nodes(const std::size_t n)
{
multiallocation_chain nodes;
std::size_t i = 0;
@@ -143,32 +129,26 @@
this->deallocate_nodes(nodes, i);
throw;
}
- return nodes.get_it();
- }
-
- //!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain &nodes)
- {
- this->deallocate_nodes(nodes.get_it());
- nodes.reset();
+ return boost::interprocess::move(nodes);
}
//!Deallocates the first n nodes of a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain &nodes, std::size_t num)
+ void deallocate_nodes(multiallocation_chain &nodes, std::size_t n)
{
- assert(nodes.size() >= num);
- for(std::size_t i = 0; i < num; ++i){
- deallocate_node(nodes.pop_front());
+ for(std::size_t i = 0; i < n; ++i){
+ void *p = detail::get_pointer(nodes.front());
+ assert(p);
+ nodes.pop_front();
+ this->deallocate_node(p);
}
}
//!Deallocates the nodes pointed by the multiallocation iterator. Never throws
- void deallocate_nodes(multiallocation_iterator it)
+ void deallocate_nodes(multiallocation_chain chain)
{
- multiallocation_iterator itend;
- while(it != itend){
- void *addr = &*it;
- ++it;
+ while(!chain.empty()){
+ void *addr = detail::get_pointer(chain.front());
+ chain.pop_front();
deallocate_node(addr);
}
}
@@ -347,7 +327,7 @@
}
private:
- typedef typename pointer_to_other
+ typedef typename boost::pointer_to_other
<void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
const std::size_t m_nodes_per_block;
Modified: trunk/boost/interprocess/allocators/node_allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/node_allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/node_allocator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,6 +18,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
@@ -77,9 +79,9 @@
public:
//-------
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
@@ -89,13 +91,9 @@
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef detail::version_type<node_allocator_base, Version> version;
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef typename SegmentManager::
- multiallocation_chain multiallocation_chain;
+ typedef boost::interprocess::version_type<node_allocator_base, Version> version;
+ typedef detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
//!Obtains node_allocator_base from
//!node_allocator_base
@@ -251,7 +249,7 @@
typedef detail::node_allocator_base
< 2, T, SegmentManager, NodesPerBlock> base_t;
public:
- typedef detail::version_type<node_allocator, 2> version;
+ typedef boost::interprocess::version_type<node_allocator, 2> version;
template<class T2>
struct rebind
@@ -373,7 +371,7 @@
size_type size(const pointer &p) const;
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -384,12 +382,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -397,7 +395,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -410,7 +408,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements);
+ multiallocation_chain allocate_individual(std::size_t num_elements);
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -423,7 +421,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it);
+ void deallocate_individual(multiallocation_chain chain);
#endif
};
Modified: trunk/boost/interprocess/allocators/private_adaptive_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/private_adaptive_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/private_adaptive_pool.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,6 +18,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
@@ -78,9 +80,9 @@
/// @endcond
public:
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
@@ -89,14 +91,10 @@
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef detail::version_type
+ typedef boost::interprocess::version_type
<private_adaptive_pool_base, Version> version;
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef typename SegmentManager::
- multiallocation_chain multiallocation_chain;
+ typedef detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
//!Obtains node_allocator from other node_allocator
template<class T2>
@@ -264,7 +262,7 @@
typedef detail::private_adaptive_pool_base
< 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
public:
- typedef detail::version_type<private_adaptive_pool, 2> version;
+ typedef boost::interprocess::version_type<private_adaptive_pool, 2> version;
template<class T2>
struct rebind
@@ -388,7 +386,7 @@
size_type size(const pointer &p) const;
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -399,12 +397,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -412,7 +410,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -425,7 +423,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements);
+ multiallocation_chain allocate_individual(std::size_t num_elements);
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -438,7 +436,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it);
+ void deallocate_individual(multiallocation_chain chain);
#endif
};
Modified: trunk/boost/interprocess/allocators/private_node_allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/private_node_allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/private_node_allocator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,6 +18,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
@@ -72,9 +74,9 @@
/// @endcond
public:
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
typedef typename detail::add_reference
@@ -83,14 +85,10 @@
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef detail::version_type
+ typedef boost::interprocess::version_type
<private_node_allocator_base, Version> version;
- typedef transform_iterator
- < typename SegmentManager::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
- typedef typename SegmentManager::
- multiallocation_chain multiallocation_chain;
+ typedef detail::transform_multiallocation_chain
+ <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
//!Obtains node_allocator from other node_allocator
template<class T2>
@@ -240,7 +238,7 @@
typedef detail::private_node_allocator_base
< 2, T, SegmentManager, NodesPerBlock> base_t;
public:
- typedef detail::version_type<private_node_allocator, 2> version;
+ typedef boost::interprocess::version_type<private_node_allocator, 2> version;
template<class T2>
struct rebind
@@ -364,7 +362,7 @@
size_type size(const pointer &p) const;
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -375,12 +373,12 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+ multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
//!contiguous block
//!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+ multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -388,7 +386,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
@@ -401,7 +399,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_iterator allocate_individual(std::size_t num_elements);
+ multiallocation_chain allocate_individual(std::size_t num_elements);
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
@@ -414,7 +412,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_iterator it);
+ void deallocate_individual(multiallocation_chain chain);
#endif
};
Modified: trunk/boost/interprocess/anonymous_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/anonymous_shared_memory.hpp (original)
+++ trunk/boost/interprocess/anonymous_shared_memory.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,7 +19,7 @@
#include <boost/interprocess/mapped_region.hpp>
#include <cstddef>
-#if (!defined(BOOST_WINDOWS)) || defined(BOOST_DISABLE_WIN32)
+#if (!defined(BOOST_INTERPROCESS_WINDOWS))
# include <fcntl.h> //open, O_CREAT, O_*...
# include <sys/mman.h> //mmap
# include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
@@ -42,12 +42,7 @@
class raw_mapped_region_creator
{
public:
- static
- #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- mapped_region
- #else
- move_return<mapped_region>
- #endif
+ static mapped_region
create_posix_mapped_region(void *address, offset_t offset, std::size_t size)
{
mapped_region region;
@@ -67,14 +62,10 @@
//!Otherwise the operating system will choose the mapping address.
//!The function returns a mapped_region holding that segment or throws
//!interprocess_exception if the function fails.
-static
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
-mapped_region
-#else
-detail::move_return<mapped_region>
-#endif
+//static mapped_region
+static mapped_region
anonymous_shared_memory(std::size_t size, void *address = 0)
-#if (!defined(BOOST_WINDOWS)) || defined(BOOST_DISABLE_WIN32)
+#if (!defined(BOOST_INTERPROCESS_WINDOWS))
{
int flags;
int fd = -1;
@@ -115,8 +106,7 @@
#else
{
windows_shared_memory anonymous_mapping(create_only, 0, read_write, size);
- mapped_region region(anonymous_mapping, read_write, 0, size, address);
- return region;
+ return mapped_region(anonymous_mapping, read_write, 0, size, address);
}
#endif
Added: trunk/boost/interprocess/containers/allocation_type.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/allocation_type.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,40 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_CONTAINERS_ALLOCATION_TYPE_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_ALLOCATION_TYPE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/allocation_type.hpp>
+
+namespace boost {
+namespace interprocess {
+
+/// @cond
+typedef int allocation_type;
+/// @endcond
+static const allocation_type allocate_new = boost::interprocess_container::allocate_new;
+static const allocation_type expand_fwd = boost::interprocess_container::expand_fwd;
+static const allocation_type expand_bwd = boost::interprocess_container::expand_bwd;
+static const allocation_type shrink_in_place = boost::interprocess_container::shrink_in_place;
+static const allocation_type try_shrink_in_place= boost::interprocess_container::try_shrink_in_place;
+static const allocation_type nothrow_allocation = boost::interprocess_container::nothrow_allocation;
+static const allocation_type zero_memory = boost::interprocess_container::zero_memory;
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
Added: trunk/boost/interprocess/containers/container/containers_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/containers_fwd.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,153 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+#define BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Standard predeclarations
+//////////////////////////////////////////////////////////////////////////////
+
+/// @cond
+
+namespace boost{
+namespace intrusive{
+ //Create namespace to avoid compilation errors
+}}
+
+namespace boost{ namespace interprocess_container{ namespace containers_detail{
+
+namespace bi = boost::intrusive;
+
+}}}
+
+namespace std {
+
+template <class T>
+class allocator;
+
+template <class T>
+struct less;
+
+template <class T1, class T2>
+struct pair;
+
+template <class CharType>
+struct char_traits;
+
+} //namespace std {
+
+/// @endcond
+
+//////////////////////////////////////////////////////////////////////////////
+// Containers
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class vector;
+
+//vector class
+template <class T
+,class A = std::allocator<T> >
+class deque;
+
+//list class
+template <class T
+ ,class A = std::allocator<T> >
+class list;
+
+//slist class
+template <class T
+ ,class Alloc = std::allocator<T> >
+class slist;
+
+//set class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class set;
+
+//multiset class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class multiset;
+
+//map class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<const Key, T> > >
+class map;
+
+//multimap class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<const Key, T> > >
+class multimap;
+
+//flat_set class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class flat_set;
+
+//flat_multiset class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class flat_multiset;
+
+//flat_map class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<Key, T> > >
+class flat_map;
+
+//flat_multimap class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<Key, T> > >
+class flat_multimap;
+
+//basic_string class
+template <class CharT
+ ,class Traits = std::char_traits<CharT>
+ ,class Alloc = std::allocator<CharT> >
+class basic_string;
+
+//string class
+typedef basic_string
+ <char
+ ,std::char_traits<char>
+ ,std::allocator<char> >
+string;
+
+}} //namespace boost { namespace interprocess_container {
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+
Added: trunk/boost/interprocess/containers/container/deque.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/deque.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1482 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2006. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_deque.h and stl_uninitialized.h files.
+// Modified by Ion Gaztanaga 2005.
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DEQUE_HPP
+#define BOOST_CONTAINERS_DEQUE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/iterators.hpp>
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <cstddef>
+#include <iterator>
+#include <cassert>
+#include <memory>
+#include <algorithm>
+#include <stdexcept>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/containers/container/detail/advanced_insert_int.hpp>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+template <class T, class Alloc>
+class deque;
+
+template <class T, class A>
+struct deque_value_traits
+{
+ typedef T value_type;
+ typedef A allocator_type;
+ static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr_after_move =
+ boost::interprocess::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_copy = has_trivial_copy<value_type>::value;
+ static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
+ static const bool trivial_assign = has_trivial_assign<value_type>::value;
+ static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
+
+};
+
+// Note: this function is simply a kludge to work around several compilers'
+// bugs in handling constant expressions.
+inline std::size_t deque_buf_size(std::size_t size)
+ { return size < 512 ? std::size_t(512 / size) : std::size_t(1); }
+
+// Deque base class. It has two purposes. First, its constructor
+// and destructor allocate (but don't initialize) storage. This makes
+// exception safety easier.
+template <class T, class Alloc>
+class deque_base
+{
+ public:
+ typedef typename Alloc::value_type val_alloc_val;
+ typedef typename Alloc::pointer val_alloc_ptr;
+ typedef typename Alloc::const_pointer val_alloc_cptr;
+ typedef typename Alloc::reference val_alloc_ref;
+ typedef typename Alloc::const_reference val_alloc_cref;
+ typedef typename Alloc::value_type val_alloc_diff;
+ typedef typename Alloc::template rebind
+ <typename Alloc::pointer>::other ptr_alloc_t;
+ typedef typename ptr_alloc_t::value_type ptr_alloc_val;
+ typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
+ typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
+ typedef typename ptr_alloc_t::reference ptr_alloc_ref;
+ typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
+ typedef typename Alloc::template
+ rebind<T>::other allocator_type;
+ typedef allocator_type stored_allocator_type;
+
+ protected:
+
+ typedef deque_value_traits<T, Alloc> traits_t;
+ typedef typename Alloc::template
+ rebind<typename Alloc::pointer>::other map_allocator_type;
+
+ static std::size_t s_buffer_size() { return deque_buf_size(sizeof(T)); }
+
+ val_alloc_ptr priv_allocate_node()
+ { return this->alloc().allocate(s_buffer_size()); }
+
+ void priv_deallocate_node(val_alloc_ptr p)
+ { this->alloc().deallocate(p, s_buffer_size()); }
+
+ ptr_alloc_ptr priv_allocate_map(std::size_t n)
+ { return this->ptr_alloc().allocate(n); }
+
+ void priv_deallocate_map(ptr_alloc_ptr p, std::size_t n)
+ { this->ptr_alloc().deallocate(p, n); }
+
+ public:
+ // Class invariants:
+ // For any nonsingular iterator i:
+ // i.node is the address of an element in the map array. The
+ // contents of i.node is a pointer to the beginning of a node.
+ // i.first == //(i.node)
+ // i.last == i.first + node_size
+ // i.cur is a pointer in the range [i.first, i.last). NOTE:
+ // the implication of this is that i.cur is always a dereferenceable
+ // pointer, even if i is a past-the-end iterator.
+ // Start and Finish are always nonsingular iterators. NOTE: this means
+ // that an empty deque must have one node, and that a deque
+ // with N elements, where N is the buffer size, must have two nodes.
+ // For every node other than start.node and finish.node, every element
+ // in the node is an initialized object. If start.node == finish.node,
+ // then [start.cur, finish.cur) are initialized objects, and
+ // the elements outside that range are uninitialized storage. Otherwise,
+ // [start.cur, start.last) and [finish.first, finish.cur) are initialized
+ // objects, and [start.first, start.cur) and [finish.cur, finish.last)
+ // are uninitialized storage.
+ // [map, map + map_size) is a valid, non-empty range.
+ // [start.node, finish.node] is a valid range contained within
+ // [map, map + map_size).
+ // A pointer in the range [map, map + map_size) points to an allocated node
+ // if and only if the pointer is in the range [start.node, finish.node].
+ class const_iterator
+ : public std::iterator<std::random_access_iterator_tag,
+ val_alloc_val, val_alloc_diff,
+ val_alloc_cptr, val_alloc_cref>
+ {
+ public:
+ static std::size_t s_buffer_size() { return deque_base<T, Alloc>::s_buffer_size(); }
+
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef val_alloc_val value_type;
+ typedef val_alloc_cptr pointer;
+ typedef val_alloc_cref reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef ptr_alloc_ptr index_pointer;
+ typedef const_iterator self_t;
+
+ friend class deque<T, Alloc>;
+ friend class deque_base<T, Alloc>;
+
+ protected:
+ val_alloc_ptr m_cur;
+ val_alloc_ptr m_first;
+ val_alloc_ptr m_last;
+ index_pointer m_node;
+
+ public:
+ const_iterator(val_alloc_ptr x, index_pointer y)
+ : m_cur(x), m_first(*y),
+ m_last(*y + s_buffer_size()), m_node(y) {}
+
+ const_iterator() : m_cur(0), m_first(0), m_last(0), m_node(0) {}
+
+ const_iterator(const const_iterator& x)
+ : m_cur(x.m_cur), m_first(x.m_first),
+ m_last(x.m_last), m_node(x.m_node) {}
+
+ reference operator*() const
+ { return *this->m_cur; }
+
+ pointer operator->() const
+ { return this->m_cur; }
+
+ difference_type operator-(const self_t& x) const
+ {
+ if(!this->m_cur && !x.m_cur){
+ return 0;
+ }
+ return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
+ (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
+ }
+
+ self_t& operator++()
+ {
+ ++this->m_cur;
+ if (this->m_cur == this->m_last) {
+ this->priv_set_node(this->m_node + 1);
+ this->m_cur = this->m_first;
+ }
+ return *this;
+ }
+
+ self_t operator++(int)
+ {
+ self_t tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ self_t& operator--()
+ {
+ if (this->m_cur == this->m_first) {
+ this->priv_set_node(this->m_node - 1);
+ this->m_cur = this->m_last;
+ }
+ --this->m_cur;
+ return *this;
+ }
+
+ self_t operator--(int)
+ {
+ self_t tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ self_t& operator+=(difference_type n)
+ {
+ difference_type offset = n + (this->m_cur - this->m_first);
+ if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
+ this->m_cur += n;
+ else {
+ difference_type node_offset =
+ offset > 0 ? offset / difference_type(this->s_buffer_size())
+ : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
+ this->priv_set_node(this->m_node + node_offset);
+ this->m_cur = this->m_first +
+ (offset - node_offset * difference_type(this->s_buffer_size()));
+ }
+ return *this;
+ }
+
+ self_t operator+(difference_type n) const
+ { self_t tmp = *this; return tmp += n; }
+
+ self_t& operator-=(difference_type n)
+ { return *this += -n; }
+
+ self_t operator-(difference_type n) const
+ { self_t tmp = *this; return tmp -= n; }
+
+ reference operator[](difference_type n) const
+ { return *(*this + n); }
+
+ bool operator==(const self_t& x) const
+ { return this->m_cur == x.m_cur; }
+
+ bool operator!=(const self_t& x) const
+ { return !(*this == x); }
+
+ bool operator<(const self_t& x) const
+ {
+ return (this->m_node == x.m_node) ?
+ (this->m_cur < x.m_cur) : (this->m_node < x.m_node);
+ }
+
+ bool operator>(const self_t& x) const
+ { return x < *this; }
+
+ bool operator<=(const self_t& x) const
+ { return !(x < *this); }
+
+ bool operator>=(const self_t& x) const
+ { return !(*this < x); }
+
+ void priv_set_node(index_pointer new_node)
+ {
+ this->m_node = new_node;
+ this->m_first = *new_node;
+ this->m_last = this->m_first + difference_type(this->s_buffer_size());
+ }
+
+ friend const_iterator operator+(std::ptrdiff_t n, const const_iterator& x)
+ { return x + n; }
+ };
+
+ //Deque iterator
+ class iterator : public const_iterator
+ {
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef val_alloc_val value_type;
+ typedef val_alloc_ptr pointer;
+ typedef val_alloc_ref reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef ptr_alloc_ptr index_pointer;
+ typedef const_iterator self_t;
+
+ friend class deque<T, Alloc>;
+ friend class deque_base<T, Alloc>;
+
+ private:
+ explicit iterator(const const_iterator& x) : const_iterator(x){}
+
+ public:
+ //Constructors
+ iterator(val_alloc_ptr x, index_pointer y) : const_iterator(x, y){}
+ iterator() : const_iterator(){}
+ //iterator(const const_iterator &cit) : const_iterator(cit){}
+ iterator(const iterator& x) : const_iterator(x){}
+
+ //Pointer like operators
+ reference operator*() const { return *this->m_cur; }
+ pointer operator->() const { return this->m_cur; }
+
+ reference operator[](difference_type n) const { return *(*this + n); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->const_iterator::operator++(); return *this; }
+
+ iterator operator++(int)
+ { iterator tmp = *this; ++*this; return tmp; }
+
+ iterator& operator--()
+ { this->const_iterator::operator--(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp = *this; --*this; return tmp; }
+
+ // Arithmetic
+ iterator& operator+=(difference_type off)
+ { this->const_iterator::operator+=(off); return *this; }
+
+ iterator operator+(difference_type off) const
+ { return iterator(this->const_iterator::operator+(off)); }
+
+ friend iterator operator+(difference_type off, const iterator& right)
+ { return iterator(off+static_cast<const const_iterator &>(right)); }
+
+ iterator& operator-=(difference_type off)
+ { this->const_iterator::operator-=(off); return *this; }
+
+ iterator operator-(difference_type off) const
+ { return iterator(this->const_iterator::operator-(off)); }
+
+ difference_type operator-(const const_iterator& right) const
+ { return static_cast<const const_iterator&>(*this) - right; }
+ };
+
+ deque_base(const allocator_type& a, std::size_t num_elements)
+ : members_(a)
+ { this->priv_initialize_map(num_elements); }
+
+ deque_base(const allocator_type& a)
+ : members_(a)
+ {}
+
+ ~deque_base()
+ {
+ if (this->members_.m_map) {
+ this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ }
+ }
+
+ private:
+ deque_base(const deque_base&);
+
+ protected:
+
+ void priv_initialize_map(std::size_t num_elements)
+ {
+// if(num_elements){
+ std::size_t num_nodes = num_elements / s_buffer_size() + 1;
+
+ this->members_.m_map_size = containers_detail::max_value((std::size_t) InitialMapSize, num_nodes + 2);
+ this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
+
+ ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
+ ptr_alloc_ptr nfinish = nstart + num_nodes;
+
+ BOOST_TRY {
+ this->priv_create_nodes(nstart, nfinish);
+ }
+ BOOST_CATCH(...){
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ this->members_.m_map = 0;
+ this->members_.m_map_size = 0;
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+
+ this->members_.m_start.priv_set_node(nstart);
+ this->members_.m_finish.priv_set_node(nfinish - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
+ num_elements % s_buffer_size();
+// }
+ }
+
+ void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+ {
+ ptr_alloc_ptr cur;
+ BOOST_TRY {
+ for (cur = nstart; cur < nfinish; ++cur)
+ *cur = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_nodes(nstart, cur);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+ {
+ for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
+ this->priv_deallocate_node(*n);
+ }
+
+ enum { InitialMapSize = 8 };
+
+ protected:
+ struct members_holder
+ : public ptr_alloc_t
+ , public allocator_type
+ {
+ members_holder(const allocator_type &a)
+ : map_allocator_type(a), allocator_type(a)
+ , m_map(0), m_map_size(0)
+ , m_start(), m_finish(m_start)
+ {}
+
+ ptr_alloc_ptr m_map;
+ std::size_t m_map_size;
+ iterator m_start;
+ iterator m_finish;
+ } members_;
+
+ ptr_alloc_t &ptr_alloc()
+ { return members_; }
+
+ const ptr_alloc_t &ptr_alloc() const
+ { return members_; }
+
+ allocator_type &alloc()
+ { return members_; }
+
+ const allocator_type &alloc() const
+ { return members_; }
+};
+/// @endcond
+
+//! Deque class
+//!
+template <class T, class Alloc>
+class deque : protected deque_base<T, Alloc>
+{
+ /// @cond
+ typedef deque_base<T, Alloc> Base;
+
+ public: // Basic types
+ typedef typename Alloc::value_type val_alloc_val;
+ typedef typename Alloc::pointer val_alloc_ptr;
+ typedef typename Alloc::const_pointer val_alloc_cptr;
+ typedef typename Alloc::reference val_alloc_ref;
+ typedef typename Alloc::const_reference val_alloc_cref;
+ typedef typename Alloc::template
+ rebind<val_alloc_ptr>::other ptr_alloc_t;
+ typedef typename ptr_alloc_t::value_type ptr_alloc_val;
+ typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
+ typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
+ typedef typename ptr_alloc_t::reference ptr_alloc_ref;
+ typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
+ /// @endcond
+
+ typedef T value_type;
+ typedef val_alloc_ptr pointer;
+ typedef val_alloc_cptr const_pointer;
+ typedef val_alloc_ref reference;
+ typedef val_alloc_cref const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef typename Base::allocator_type allocator_type;
+
+ public: // Iterators
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ /// @cond
+ private: // Internal typedefs
+ typedef ptr_alloc_ptr index_pointer;
+ static std::size_t s_buffer_size()
+ { return Base::s_buffer_size(); }
+ typedef containers_detail::advanced_insert_aux_int<value_type, iterator> advanced_insert_aux_int_t;
+ typedef repeat_iterator<T, difference_type> r_iterator;
+ typedef boost::interprocess::move_iterator<r_iterator> move_it;
+
+ /// @endcond
+
+ allocator_type get_allocator() const { return Base::alloc(); }
+
+ public: // Basic accessors
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(deque)
+
+ iterator begin()
+ { return this->members_.m_start; }
+
+ iterator end()
+ { return this->members_.m_finish; }
+
+ const_iterator begin() const
+ { return this->members_.m_start; }
+
+ const_iterator end() const
+ { return this->members_.m_finish; }
+
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->members_.m_finish); }
+
+ reverse_iterator rend()
+ { return reverse_iterator(this->members_.m_start); }
+
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator(this->members_.m_finish); }
+
+ const_reverse_iterator rend() const
+ { return const_reverse_iterator(this->members_.m_start); }
+
+ const_iterator cbegin() const
+ { return this->members_.m_start; }
+
+ const_iterator cend() const
+ { return this->members_.m_finish; }
+
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->members_.m_finish); }
+
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->members_.m_start); }
+
+ reference operator[](size_type n)
+ { return this->members_.m_start[difference_type(n)]; }
+
+ const_reference operator[](size_type n) const
+ { return this->members_.m_start[difference_type(n)]; }
+
+ void priv_range_check(size_type n) const
+ { if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
+
+ reference at(size_type n)
+ { this->priv_range_check(n); return (*this)[n]; }
+
+ const_reference at(size_type n) const
+ { this->priv_range_check(n); return (*this)[n]; }
+
+ reference front() { return *this->members_.m_start; }
+
+ reference back() { return *(end()-1); }
+
+ const_reference front() const
+ { return *this->members_.m_start; }
+
+ const_reference back() const { return *(cend()-1); }
+
+ size_type size() const
+ { return this->members_.m_finish - this->members_.m_start; }
+
+ size_type max_size() const
+ { return this->alloc().max_size(); }
+
+ bool empty() const
+ { return this->members_.m_finish == this->members_.m_start; }
+
+ explicit deque(const allocator_type& a = allocator_type())
+ : Base(a)
+ {}
+
+ deque(const deque& x)
+ : Base(x.alloc())
+ {
+ if(x.size()){
+ this->priv_initialize_map(x.size());
+ std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start);
+ }
+ }
+
+ deque(BOOST_INTERPROCESS_RV_REF(deque) mx)
+ : Base(mx.alloc())
+ { this->swap(mx); }
+
+ deque(size_type n, const value_type& value,
+ const allocator_type& a = allocator_type()) : Base(a, n)
+ { this->priv_fill_initialize(value); }
+
+ explicit deque(size_type n) : Base(allocator_type(), n)
+ { this->resize(n); }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template <class InpIt>
+ deque(InpIt first, InpIt last, const allocator_type& a = allocator_type())
+ : Base(a)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_initialize_dispatch(first, last, Result());
+ }
+
+ ~deque()
+ {
+ priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+ }
+
+ deque& operator= (const deque& x)
+ {
+ const size_type len = size();
+ if (&x != this) {
+ if (len >= x.size())
+ this->erase(std::copy(x.begin(), x.end(), this->members_.m_start), this->members_.m_finish);
+ else {
+ const_iterator mid = x.begin() + difference_type(len);
+ std::copy(x.begin(), mid, this->members_.m_start);
+ this->insert(this->members_.m_finish, mid, x.end());
+ }
+ }
+ return *this;
+ }
+
+ deque& operator= (BOOST_INTERPROCESS_RV_REF(deque) x)
+ {
+ this->clear();
+ this->swap(x);
+ return *this;
+ }
+
+ void swap(deque &x)
+ {
+ std::swap(this->members_.m_start, x.members_.m_start);
+ std::swap(this->members_.m_finish, x.members_.m_finish);
+ std::swap(this->members_.m_map, x.members_.m_map);
+ std::swap(this->members_.m_map_size, x.members_.m_map_size);
+ }
+
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
+
+ template <class InpIt>
+ void assign(InpIt first, InpIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ void push_back(const value_type& t)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(t);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), size_type(1), t);
+ }
+ }
+
+ void push_back(BOOST_INTERPROCESS_RV_REF(value_type) t)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(boost::interprocess::move(t));
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ }
+ }
+
+ void push_front(const value_type& t)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(t);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), size_type(1), t);
+ }
+ }
+
+ void push_front(BOOST_INTERPROCESS_RV_REF(value_type) t)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(boost::interprocess::move(t));
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ }
+ }
+
+ void pop_back()
+ {
+ if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
+ --this->members_.m_finish.m_cur;
+ containers_detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
+ }
+ else
+ this->priv_pop_back_aux();
+ }
+
+ void pop_front()
+ {
+ if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
+ containers_detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
+ ++this->members_.m_start.m_cur;
+ }
+ else
+ this->priv_pop_front_aux();
+ }
+
+ iterator insert(const_iterator position, const value_type& x)
+ {
+ if (position == cbegin()){
+ this->push_front(x);
+ return begin();
+ }
+ else if (position == cend()){
+ this->push_back(x);
+ return (end()-1);
+ }
+ else {
+ size_type n = position - cbegin();
+ this->priv_insert_aux(position, size_type(1), x);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(value_type) mx)
+ {
+ if (position == cbegin()) {
+ this->push_front(boost::interprocess::move(mx));
+ return begin();
+ }
+ else if (position == cend()) {
+ this->push_back(boost::interprocess::move(mx));
+ return(end()-1);
+ }
+ else {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type n = position - begin();
+ this->priv_insert_aux(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
+ return iterator(this->begin() + n);
+ }
+ }
+
+ void insert(const_iterator pos, size_type n, const value_type& x)
+ { this->priv_fill_insert(pos, n, x); }
+
+ // Check whether it's an integral type. If so, it's not an iterator.
+ template <class InpIt>
+ void insert(const_iterator pos, InpIt first, InpIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(pos, first, last, Result());
+ }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(boost::interprocess::forward<Args>(args)...);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(boost::interprocess::forward<Args>(args)...);
+ this->priv_insert_aux_impl(this->cend(), 1, proxy);
+ }
+ }
+
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(boost::interprocess::forward<Args>(args)...);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(boost::interprocess::forward<Args>(args)...);
+ this->priv_insert_aux_impl(this->cbegin(), 1, proxy);
+ }
+ }
+
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ {
+ if(p == this->cbegin()){
+ this->emplace_front(boost::interprocess::forward<Args>(args)...);
+ return this->begin();
+ }
+ else if(p == this->cend()){
+ this->emplace_back(boost::interprocess::forward<Args>(args)...);
+ return (this->end()-1);
+ }
+ else{
+ size_type n = p - this->cbegin();
+ containers_detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(boost::interprocess::forward<Args>(args)...);
+ this->priv_insert_aux_impl(p, 1, proxy);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_back()
+ {
+ if(priv_push_front_simple_available()){
+ new(priv_push_front_simple_pos())value_type();
+ priv_push_front_simple_commit();
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(cend(), 1, proxy);
+ }
+ }
+
+ void emplace_front()
+ {
+ if(priv_push_front_simple_available()){
+ new(priv_push_front_simple_pos())value_type();
+ priv_push_front_simple_commit();
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(cbegin(), 1, proxy);
+ }
+ }
+
+ iterator emplace(const_iterator p)
+ {
+ if(p == cbegin()){
+ emplace_front();
+ return begin();
+ }
+ else if(p == cend()){
+ emplace_back();
+ return (end()-1);
+ }
+ else{
+ size_type n = p - cbegin();
+ containers_detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(p, 1, proxy);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ //advanced_insert_int.hpp includes all necessary preprocessor machinery...
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ if(priv_push_back_simple_available()){ \
+ new(priv_push_back_simple_pos())value_type \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_push_back_simple_commit(); \
+ } \
+ else{ \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_insert_aux_impl(cend(), 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ if(priv_push_front_simple_available()){ \
+ new(priv_push_front_simple_pos())value_type \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_push_front_simple_commit(); \
+ } \
+ else{ \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_insert_aux_impl(cbegin(), 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ if(p == this->cbegin()){ \
+ this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ return this->begin(); \
+ } \
+ else if(p == cend()){ \
+ this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ return (this->end()-1); \
+ } \
+ else{ \
+ size_type pos_num = p - this->cbegin(); \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ this->priv_insert_aux_impl(p, 1, proxy); \
+ return iterator(this->begin() + pos_num); \
+ } \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ void resize(size_type new_size, const value_type& x)
+ {
+ const size_type len = size();
+ if (new_size < len)
+ this->erase(this->members_.m_start + new_size, this->members_.m_finish);
+ else
+ this->insert(this->members_.m_finish, new_size - len, x);
+ }
+
+ void resize(size_type new_size)
+ {
+ const size_type len = size();
+ if (new_size < len)
+ this->erase(this->members_.m_start + new_size, this->members_.m_finish);
+ else{
+ size_type n = new_size - this->size();
+ containers_detail::default_construct_aux_proxy<T, iterator, size_type> proxy(n);
+ priv_insert_aux_impl(this->cend(), n, proxy);
+ }
+ }
+
+ iterator erase(const_iterator pos)
+ {
+ const_iterator next = pos;
+ ++next;
+ difference_type index = pos - this->members_.m_start;
+ if (size_type(index) < (this->size() >> 1)) {
+ boost::interprocess::move_backward(begin(), iterator(pos), iterator(next));
+ pop_front();
+ }
+ else {
+ boost::interprocess::move(iterator(next), end(), iterator(pos));
+ pop_back();
+ }
+ return this->members_.m_start + index;
+ }
+
+ iterator erase(const_iterator first, const_iterator last)
+ {
+ if (first == this->members_.m_start && last == this->members_.m_finish) {
+ this->clear();
+ return this->members_.m_finish;
+ }
+ else {
+ difference_type n = last - first;
+ difference_type elems_before = first - this->members_.m_start;
+ if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
+ boost::interprocess::move_backward(begin(), iterator(first), iterator(last));
+ iterator new_start = this->members_.m_start + n;
+ if(!Base::traits_t::trivial_dctr_after_move)
+ this->priv_destroy_range(this->members_.m_start, new_start);
+ this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
+ this->members_.m_start = new_start;
+ }
+ else {
+ boost::interprocess::move(iterator(last), end(), iterator(first));
+ iterator new_finish = this->members_.m_finish - n;
+ if(!Base::traits_t::trivial_dctr_after_move)
+ this->priv_destroy_range(new_finish, this->members_.m_finish);
+ this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+ this->members_.m_finish = new_finish;
+ }
+ return this->members_.m_start + elems_before;
+ }
+ }
+
+ void clear()
+ {
+ for (index_pointer node = this->members_.m_start.m_node + 1;
+ node < this->members_.m_finish.m_node;
+ ++node) {
+ this->priv_destroy_range(*node, *node + this->s_buffer_size());
+ this->priv_deallocate_node(*node);
+ }
+
+ if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
+ this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
+ this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
+ this->priv_deallocate_node(this->members_.m_finish.m_first);
+ }
+ else
+ this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
+
+ this->members_.m_finish = this->members_.m_start;
+ }
+
+ /// @cond
+ private:
+
+ bool priv_push_back_simple_available() const
+ {
+ return this->members_.m_map &&
+ (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
+ }
+
+ void *priv_push_back_simple_pos() const
+ {
+ return static_cast<void*>(containers_detail::get_pointer(this->members_.m_finish.m_cur));
+ }
+
+ void priv_push_back_simple_commit()
+ {
+ ++this->members_.m_finish.m_cur;
+ }
+
+ bool priv_push_front_simple_available() const
+ {
+ return this->members_.m_map &&
+ (this->members_.m_start.m_cur != this->members_.m_start.m_first);
+ }
+
+ void *priv_push_front_simple_pos() const
+ { return static_cast<void*>(containers_detail::get_pointer(this->members_.m_start.m_cur) - 1); }
+
+ void priv_push_front_simple_commit()
+ { --this->members_.m_start.m_cur; }
+
+ template <class InpIt>
+ void priv_insert_aux(const_iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ for(;first != last; ++first){
+ this->insert(pos, boost::interprocess::move(value_type(*first)));
+ }
+ }
+
+ template <class FwdIt>
+ void priv_insert_aux(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ { this->priv_insert_aux(pos, first, last); }
+
+ // assign(), a generalized assignment member function. Two
+ // versions: one that takes a count, and one that takes a range.
+ // The range version is a member template, so we dispatch on whether
+ // or not the type is an integer.
+ void priv_fill_assign(size_type n, const T& val)
+ {
+ if (n > size()) {
+ std::fill(begin(), end(), val);
+ this->insert(cend(), n - size(), val);
+ }
+ else {
+ this->erase(cbegin() + n, cend());
+ std::fill(begin(), end(), val);
+ }
+ }
+
+ template <class Integer>
+ void priv_initialize_dispatch(Integer n, Integer x, containers_detail::true_)
+ {
+ this->priv_initialize_map(n);
+ this->priv_fill_initialize(x);
+ }
+
+ template <class InpIt>
+ void priv_initialize_dispatch(InpIt first, InpIt last, containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
+ this->priv_range_initialize(first, last, ItCat());
+ }
+
+ void priv_destroy_range(iterator p, iterator p2)
+ {
+ for(;p != p2; ++p)
+ containers_detail::get_pointer(&*p)->~value_type();
+ }
+
+ void priv_destroy_range(pointer p, pointer p2)
+ {
+ for(;p != p2; ++p)
+ containers_detail::get_pointer(&*p)->~value_type();
+ }
+
+ template <class Integer>
+ void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
+ { this->priv_fill_assign((size_type) n, (T) val); }
+
+ template <class InpIt>
+ void priv_assign_dispatch(InpIt first, InpIt last, containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
+ this->priv_assign_aux(first, last, ItCat());
+ }
+
+ template <class InpIt>
+ void priv_assign_aux(InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ iterator cur = begin();
+ for ( ; first != last && cur != end(); ++cur, ++first)
+ *cur = *first;
+ if (first == last)
+ this->erase(cur, cend());
+ else
+ this->insert(cend(), first, last);
+ }
+
+ template <class FwdIt>
+ void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = std::distance(first, last);
+ if (len > size()) {
+ FwdIt mid = first;
+ std::advance(mid, size());
+ std::copy(first, mid, begin());
+ this->insert(cend(), mid, last);
+ }
+ else
+ this->erase(std::copy(first, last, begin()), cend());
+ }
+
+ template <class Integer>
+ void priv_insert_dispatch(const_iterator pos, Integer n, Integer x, containers_detail::true_)
+ { this->priv_fill_insert(pos, (size_type) n, (value_type) x); }
+
+ template <class InpIt>
+ void priv_insert_dispatch(const_iterator pos,InpIt first, InpIt last, containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
+ this->priv_insert_aux(pos, first, last, ItCat());
+ }
+
+ void priv_insert_aux(const_iterator pos, size_type n, const value_type& x)
+ {
+ typedef constant_iterator<value_type, difference_type> c_it;
+ this->priv_insert_aux(pos, c_it(x, n), c_it());
+ }
+
+ //Just forward all operations to priv_insert_aux_impl
+ template <class FwdIt>
+ void priv_insert_aux(const_iterator p, FwdIt first, FwdIt last)
+ {
+ containers_detail::advanced_insert_aux_proxy<T, FwdIt, iterator> proxy(first, last);
+ priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
+ }
+
+ void priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
+ {
+ iterator pos(p);
+ if(!this->members_.m_map){
+ this->priv_initialize_map(0);
+ pos = this->begin();
+ }
+
+ const difference_type elemsbefore = pos - this->members_.m_start;
+ size_type length = this->size();
+ if (elemsbefore < static_cast<difference_type>(length / 2)) {
+ iterator new_start = this->priv_reserve_elements_at_front(n);
+ iterator old_start = this->members_.m_start;
+ pos = this->members_.m_start + elemsbefore;
+ if (elemsbefore >= difference_type(n)) {
+ iterator start_n = this->members_.m_start + difference_type(n);
+ boost::interprocess::uninitialized_move(this->members_.m_start, start_n, new_start);
+ this->members_.m_start = new_start;
+ boost::interprocess::move(start_n, pos, old_start);
+ interf.copy_all_to(pos - difference_type(n));
+ }
+ else {
+ difference_type mid_count = (difference_type(n) - elemsbefore);
+ iterator mid_start = old_start - mid_count;
+ interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
+ this->members_.m_start = mid_start;
+ boost::interprocess::uninitialized_move(old_start, pos, new_start);
+ this->members_.m_start = new_start;
+ interf.copy_all_to(old_start);
+ }
+ }
+ else {
+ iterator new_finish = this->priv_reserve_elements_at_back(n);
+ iterator old_finish = this->members_.m_finish;
+ const difference_type elemsafter =
+ difference_type(length) - elemsbefore;
+ pos = this->members_.m_finish - elemsafter;
+ if (elemsafter >= difference_type(n)) {
+ iterator finish_n = this->members_.m_finish - difference_type(n);
+ boost::interprocess::uninitialized_move(finish_n, this->members_.m_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ boost::interprocess::move_backward(pos, finish_n, old_finish);
+ interf.copy_all_to(pos);
+ }
+ else {
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_finish += n-elemsafter;
+ boost::interprocess::uninitialized_move(pos, old_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ interf.copy_all_to(pos);
+ }
+ }
+ }
+
+ void priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
+ {
+ typedef constant_iterator<value_type, difference_type> c_it;
+ this->insert(pos, c_it(x, n), c_it());
+ }
+
+ // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
+ // but none of the deque's elements have yet been constructed.
+ void priv_fill_initialize(const value_type& value)
+ {
+ index_pointer cur;
+ BOOST_TRY {
+ for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
+ std::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
+ }
+ std::uninitialized_fill(this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template <class InpIt>
+ void priv_range_initialize(InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ this->priv_initialize_map(0);
+ BOOST_TRY {
+ for ( ; first != last; ++first)
+ this->push_back(*first);
+ }
+ BOOST_CATCH(...){
+ this->clear();
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template <class FwdIt>
+ void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type n = 0;
+ n = std::distance(first, last);
+ this->priv_initialize_map(n);
+
+ index_pointer cur_node;
+ BOOST_TRY {
+ for (cur_node = this->members_.m_start.m_node;
+ cur_node < this->members_.m_finish.m_node;
+ ++cur_node) {
+ FwdIt mid = first;
+ std::advance(mid, this->s_buffer_size());
+ boost::interprocess::uninitialized_copy_or_move(first, mid, *cur_node);
+ first = mid;
+ }
+ boost::interprocess::uninitialized_copy_or_move(first, last, this->members_.m_finish.m_first);
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
+ void priv_pop_back_aux()
+ {
+ this->priv_deallocate_node(this->members_.m_finish.m_first);
+ this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
+ containers_detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
+ }
+
+ // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
+ // if the deque has at least one element (a precondition for this member
+ // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
+ // must have at least two nodes.
+ void priv_pop_front_aux()
+ {
+ containers_detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
+ this->priv_deallocate_node(this->members_.m_start.m_first);
+ this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
+ }
+
+ iterator priv_reserve_elements_at_front(size_type n)
+ {
+ size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
+ if (n > vacancies){
+ size_type new_elems = n-vacancies;
+ size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
+ this->s_buffer_size();
+ size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
+ if (new_nodes > s){
+ this->priv_reallocate_map(new_nodes, true);
+ }
+ size_type i = 1;
+ BOOST_TRY {
+ for (; i <= new_nodes; ++i)
+ *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...) {
+ for (size_type j = 1; j < i; ++j)
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ return this->members_.m_start - difference_type(n);
+ }
+
+ iterator priv_reserve_elements_at_back(size_type n)
+ {
+ size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
+ if (n > vacancies){
+ size_type new_elems = n - vacancies;
+ size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
+ size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
+ if (new_nodes + 1 > s){
+ this->priv_reallocate_map(new_nodes, false);
+ }
+ size_type i;
+ BOOST_TRY {
+ for (i = 1; i <= new_nodes; ++i)
+ *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...) {
+ for (size_type j = 1; j < i; ++j)
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ return this->members_.m_finish + difference_type(n);
+ }
+
+ void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
+ {
+ size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
+ size_type new_num_nodes = old_num_nodes + nodes_to_add;
+
+ index_pointer new_nstart;
+ if (this->members_.m_map_size > 2 * new_num_nodes) {
+ new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+ + (add_at_front ? nodes_to_add : 0);
+ if (new_nstart < this->members_.m_start.m_node)
+ boost::interprocess::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ else
+ boost::interprocess::move_backward
+ (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
+ }
+ else {
+ size_type new_map_size =
+ this->members_.m_map_size + containers_detail::max_value(this->members_.m_map_size, nodes_to_add) + 2;
+
+ index_pointer new_map = this->priv_allocate_map(new_map_size);
+ new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ + (add_at_front ? nodes_to_add : 0);
+ boost::interprocess::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+
+ this->members_.m_map = new_map;
+ this->members_.m_map_size = new_map_size;
+ }
+
+ this->members_.m_start.priv_set_node(new_nstart);
+ this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
+ }
+ /// @endcond
+};
+
+// Nonmember functions.
+template <class T, class Alloc>
+inline bool operator==(const deque<T, Alloc>& x,
+ const deque<T, Alloc>& y)
+{
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class Alloc>
+inline bool operator<(const deque<T, Alloc>& x,
+ const deque<T, Alloc>& y)
+{
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T, class Alloc>
+inline bool operator!=(const deque<T, Alloc>& x,
+ const deque<T, Alloc>& y)
+ { return !(x == y); }
+
+template <class T, class Alloc>
+inline bool operator>(const deque<T, Alloc>& x,
+ const deque<T, Alloc>& y)
+ { return y < x; }
+
+template <class T, class Alloc>
+inline bool operator<=(const deque<T, Alloc>& x,
+ const deque<T, Alloc>& y)
+ { return !(y < x); }
+
+template <class T, class Alloc>
+inline bool operator>=(const deque<T, Alloc>& x,
+ const deque<T, Alloc>& y)
+ { return !(x < y); }
+
+
+template <class T, class A>
+inline void swap(deque<T, A>& x, deque<T, A>& y)
+{ x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::deque<T, A> >
+{
+ enum { value = has_trivial_destructor<A>::value };
+};
+
+}}
+
+/// @endcond
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_CONTAINERS_DEQUE_HPP
Added: trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,386 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
+#define BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <iterator> //std::iterator_traits
+#include <algorithm> //std::copy, std::uninitialized_copy
+#include <new> //placement new
+#include <cassert>
+
+namespace boost { namespace interprocess_container { namespace containers_detail {
+
+//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
+template<class T, class Iterator>
+struct advanced_insert_aux_int
+{
+ typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
+ virtual void copy_all_to(Iterator p) = 0;
+ virtual void uninitialized_copy_all_to(Iterator p) = 0;
+ virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
+ virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
+ virtual ~advanced_insert_aux_int() {}
+};
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class FwdIt, class Iterator>
+struct advanced_insert_aux_proxy
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ advanced_insert_aux_proxy(FwdIt first, FwdIt last)
+ : first_(first), last_(last)
+ {}
+
+ virtual ~advanced_insert_aux_proxy()
+ {}
+
+ virtual void copy_all_to(Iterator p)
+ { std::copy(first_, last_, p); }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ { boost::interprocess::uninitialized_copy_or_move(first_, last_, p); }
+
+ virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ {
+ FwdIt mid = first_;
+ std::advance(mid, division_count);
+ if(first_n){
+ boost::interprocess::uninitialized_copy_or_move(first_, mid, pos);
+ first_ = mid;
+ }
+ else{
+ boost::interprocess::uninitialized_copy_or_move(mid, last_, pos);
+ last_ = mid;
+ }
+ }
+
+ virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ {
+ FwdIt mid = first_;
+ std::advance(mid, division_count);
+ if(first_n){
+ std::copy(first_, mid, pos);
+ first_ = mid;
+ }
+ else{
+ std::copy(mid, last_, pos);
+ last_ = mid;
+ }
+ }
+
+ FwdIt first_, last_;
+};
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class Iterator, class SizeType>
+struct default_construct_aux_proxy
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ default_construct_aux_proxy(SizeType count)
+ : count_(count)
+ {}
+
+ void uninitialized_copy_impl(Iterator p, const SizeType n)
+ {
+ assert(n <= count_);
+ Iterator orig_p = p;
+ SizeType i = 0;
+ try{
+ for(; i < n; ++i, ++p){
+ new(containers_detail::get_pointer(&*p))T();
+ }
+ }
+ catch(...){
+ while(i--){
+ containers_detail::get_pointer(&*orig_p++)->~T();
+ }
+ throw;
+ }
+ count_ -= n;
+ }
+
+ virtual ~default_construct_aux_proxy()
+ {}
+
+ virtual void copy_all_to(Iterator)
+ { //This should never be called with any count
+ assert(count_ == 0);
+ }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ { this->uninitialized_copy_impl(p, count_); }
+
+ virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ {
+ SizeType new_count;
+ if(first_n){
+ new_count = division_count;
+ }
+ else{
+ assert(difference_type(count_)>= division_count);
+ new_count = count_ - division_count;
+ }
+ this->uninitialized_copy_impl(pos, new_count);
+ }
+
+ virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
+ {
+ assert(count_ == 0);
+ SizeType new_count;
+ if(first_n){
+ new_count = division_count;
+ }
+ else{
+ assert(difference_type(count_)>= division_count);
+ new_count = count_ - division_count;
+ }
+ //This function should never called with a count different to zero
+ assert(new_count == 0);
+ (void)new_count;
+ }
+
+ SizeType count_;
+};
+
+}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#include <boost/interprocess/containers/container/detail/variadic_templates_tools.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <typeinfo>
+//#include <iostream> //For debugging purposes
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class Iterator, class ...Args>
+struct advanced_insert_aux_emplace
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+ advanced_insert_aux_emplace(Args&&... args)
+ : args_(args...), used_(false)
+ {}
+
+ ~advanced_insert_aux_emplace()
+ {}
+
+ virtual void copy_all_to(Iterator p)
+ { this->priv_copy_all_to(index_tuple_t(), p); }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ { this->priv_uninitialized_copy_all_to(index_tuple_t(), p); }
+
+ virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
+
+ virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ { this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
+
+ private:
+ template<int ...IdxPack>
+ void priv_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
+ {
+ if(!used_){
+ T object(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
+ *p = boost::interprocess::move(object);
+ used_ = true;
+ }
+ }
+
+ template<int ...IdxPack>
+ void priv_uninitialized_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
+ {
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
+ used_ = true;
+ }
+ }
+
+ template<int ...IdxPack>
+ void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
+ {
+ assert(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
+ used_ = true;
+ }
+ }
+ }
+
+ template<int ...IdxPack>
+ void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
+ {
+ assert(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ T object(boost::interprocess::forward<Args>(get<IdxPack>(args_))...);
+ *p = boost::interprocess::move(object);
+ used_ = true;
+ }
+ }
+ }
+ tuple<Args&&...> args_;
+ bool used_;
+};
+
+}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+
+#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#include <boost/interprocess/containers/container/detail/value_init.hpp>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class Iterator>
+struct advanced_insert_aux_emplace
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ advanced_insert_aux_emplace()
+ : used_(false)
+ {}
+
+ ~advanced_insert_aux_emplace()
+ {}
+
+ virtual void copy_all_to(Iterator p)
+ {
+ if(!used_){
+ value_init<T>v;
+ *p = boost::interprocess::move(v.m_t);
+ used_ = true;
+ }
+ }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ {
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T();
+ used_ = true;
+ }
+ }
+
+ virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ {
+ assert(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T();
+ used_ = true;
+ }
+ }
+ }
+
+ virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ {
+ assert(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ value_init<T>v;
+ *p = boost::interprocess::move(v.m_t);
+ used_ = true;
+ }
+ }
+ }
+ private:
+ bool used_;
+};
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<class T, class Iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
+ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ : public advanced_insert_aux_int<T, Iterator> \
+ { \
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type; \
+ \
+ BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
+ : used_(false), BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
+ \
+ virtual void copy_all_to(Iterator p) \
+ { \
+ if(!used_){ \
+ T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ *p = boost::interprocess::move(v); \
+ used_ = true; \
+ } \
+ } \
+ \
+ virtual void uninitialized_copy_all_to(Iterator p) \
+ { \
+ if(!used_){ \
+ new(containers_detail::get_pointer(&*p))T \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ used_ = true; \
+ } \
+ } \
+ \
+ virtual void uninitialized_copy_some_and_update \
+ (Iterator p, difference_type division_count, bool first_n) \
+ { \
+ assert(division_count <=1); \
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
+ if(!used_){ \
+ new(containers_detail::get_pointer(&*p))T \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ used_ = true; \
+ } \
+ } \
+ } \
+ \
+ virtual void copy_some_and_update \
+ (Iterator p, difference_type division_count, bool first_n) \
+ { \
+ assert(division_count <=1); \
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
+ if(!used_){ \
+ T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ *p = boost::interprocess::move(v); \
+ used_ = true; \
+ } \
+ } \
+ } \
+ \
+ bool used_; \
+ BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
+ }; \
+//!
+
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+
+#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
Added: trunk/boost/interprocess/containers/container/detail/algorithms.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/algorithms.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,215 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
+#define BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/get_pointer.hpp>
+
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/iterators.hpp>
+
+
+#include <cstring>
+
+namespace boost {
+namespace interprocess_container {
+
+#if !defined(BOOST_HAS_RVALUE_REFS)
+template<class T>
+struct has_own_construct_from_it
+{
+ static const bool value = false;
+};
+
+namespace containers_detail {
+
+template<class T, class InpIt>
+inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::true_)
+{
+ T::construct(dest, *source);
+}
+
+template<class T, class InpIt>
+inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::false_)
+{
+ new((void*)dest)T(*source);
+}
+
+} //namespace containers_detail {
+
+template<class T, class InpIt>
+inline void construct_in_place(T* dest, InpIt source)
+{
+ typedef containers_detail::bool_<has_own_construct_from_it<T>::value> boolean_t;
+ containers_detail::construct_in_place_impl(dest, source, boolean_t());
+}
+
+#else
+template<class T, class InpIt>
+inline void construct_in_place(T* dest, InpIt source)
+{ new((void*)dest)T(*source); }
+#endif
+
+template<class T, class U, class D>
+inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
+{
+ new((void*)dest)T();
+}
+
+template<class T, class U, class E>
+inline void construct_in_place(T *dest, emplace_iterator<U, E> ei)
+{
+ ei.construct_in_place(dest);
+}
+
+template<class InIt, class OutIt>
+struct optimize_assign
+{
+ static const bool value = false;
+};
+
+template<class T>
+struct optimize_assign<const T*, T*>
+{
+ static const bool value = boost::has_trivial_assign<T>::value;
+};
+
+template<class T>
+struct optimize_assign<T*, T*>
+ : public optimize_assign<const T*, T*>
+{};
+
+template<class InIt, class OutIt>
+struct optimize_copy
+{
+ static const bool value = false;
+};
+
+template<class T>
+struct optimize_copy<const T*, T*>
+{
+ static const bool value = boost::has_trivial_copy<T>::value;
+};
+
+template<class T>
+struct optimize_copy<T*, T*>
+ : public optimize_copy<const T*, T*>
+{};
+
+template<class InIt, class OutIt> inline
+OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, containers_detail::bool_<false>)
+{
+ for (; length--; ++dest, ++first)
+ *dest = *first;
+ return dest;
+}
+
+template<class T> inline
+T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
+{
+ std::size_t size = length*sizeof(T);
+ return (static_cast<T*>(std::memmove(dest, first, size))) + size;
+}
+
+template<class InIt, class OutIt> inline
+OutIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
+{
+ const bool do_optimized_assign = optimize_assign<InIt, OutIt>::value;
+ return copy_n_dispatch(first, length, dest, containers_detail::bool_<do_optimized_assign>());
+}
+
+template<class InIt, class FwdIt> inline
+FwdIt uninitialized_copy_n_dispatch
+ (InIt first,
+ typename std::iterator_traits<InIt>::difference_type count,
+ FwdIt dest, containers_detail::bool_<false>)
+{
+ typedef typename std::iterator_traits<FwdIt>::value_type value_type;
+ //Save initial destination position
+ FwdIt dest_init = dest;
+ typename std::iterator_traits<InIt>::difference_type new_count = count+1;
+
+ BOOST_TRY{
+ //Try to build objects
+ for (; --new_count; ++dest, ++first){
+ construct_in_place(containers_detail::get_pointer(&*dest), first);
+ }
+ }
+ BOOST_CATCH(...){
+ //Call destructors
+ new_count = count - new_count;
+ for (; new_count--; ++dest_init){
+ containers_detail::get_pointer(&*dest_init)->~value_type();
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ return dest;
+}
+template<class T> inline
+T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
+{
+ std::size_t size = length*sizeof(T);
+ return (static_cast<T*>(std::memmove(dest, first, size))) + size;
+}
+
+template<class InIt, class FwdIt> inline
+FwdIt uninitialized_copy_n
+ (InIt first,
+ typename std::iterator_traits<InIt>::difference_type count,
+ FwdIt dest)
+{
+ const bool do_optimized_copy = optimize_copy<InIt, FwdIt>::value;
+ return uninitialized_copy_n_dispatch(first, count, dest, containers_detail::bool_<do_optimized_copy>());
+}
+
+// uninitialized_copy_copy
+// Copies [first1, last1) into [result, result + (last1 - first1)), and
+// copies [first2, last2) into
+// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
+template <class InpIt1, class InpIt2, class FwdIt>
+FwdIt uninitialized_copy_copy
+ (InpIt1 first1, InpIt1 last1, InpIt2 first2, InpIt2 last2, FwdIt result)
+{
+ typedef typename std::iterator_traits<FwdIt>::value_type value_type;
+ FwdIt mid = std::uninitialized_copy(first1, last1, result);
+ BOOST_TRY {
+ return std::uninitialized_copy(first2, last2, mid);
+ }
+ BOOST_CATCH(...){
+ for(;result != mid; ++result){
+ containers_detail::get_pointer(&*result)->~value_type();
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+}
+
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
+
Added: trunk/boost/interprocess/containers/container/detail/allocation_type.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/allocation_type.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
+#define BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+namespace boost {
+namespace interprocess_container {
+
+/// @cond
+enum allocation_type_v
+{
+ // constants for allocation commands
+ allocate_new_v = 0x01,
+ expand_fwd_v = 0x02,
+ expand_bwd_v = 0x04,
+// expand_both = expand_fwd | expand_bwd,
+// expand_or_new = allocate_new | expand_both,
+ shrink_in_place_v = 0x08,
+ nothrow_allocation_v = 0x10,
+ zero_memory_v = 0x20,
+ try_shrink_in_place_v = 0x40
+};
+
+typedef int allocation_type;
+/// @endcond
+static const allocation_type allocate_new = (allocation_type)allocate_new_v;
+static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
+static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
+static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
+static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
+static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
+static const allocation_type zero_memory = (allocation_type)zero_memory_v;
+
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
Added: trunk/boost/interprocess/containers/container/detail/config_begin.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/config_begin.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,47 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
+#define BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
+#include <boost/config.hpp>
+#endif
+
+#ifdef BOOST_MSVC
+ #ifndef _CRT_SECURE_NO_DEPRECATE
+ #define BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
+ #define _CRT_SECURE_NO_DEPRECATE
+ #endif
+ #pragma warning (push)
+ #pragma warning (disable : 4702) // unreachable code
+ #pragma warning (disable : 4706) // assignment within conditional expression
+ #pragma warning (disable : 4127) // conditional expression is constant
+ #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+ #pragma warning (disable : 4284) // odd return type for operator->
+ #pragma warning (disable : 4244) // possible loss of data
+ #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
+ #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
+ #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
+ #pragma warning (disable : 4355) // "this" : used in base member initializer list
+ #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
+ #pragma warning (disable : 4511) // copy constructor could not be generated
+ #pragma warning (disable : 4512) // assignment operator could not be generated
+ #pragma warning (disable : 4514) // unreferenced inline removed
+ #pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
+ #pragma warning (disable : 4522) // "class" : multiple assignment operators specified
+ #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
+ #pragma warning (disable : 4710) // function not inlined
+ #pragma warning (disable : 4711) // function selected for automatic inline expansion
+ #pragma warning (disable : 4786) // identifier truncated in debug info
+ #pragma warning (disable : 4996) // "function": was declared deprecated
+ #pragma warning (disable : 4197) // top-level volatile in cast is ignored
+ #pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
+ // with /GR-; unpredictable behavior may result
+ #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
+ #pragma warning (disable : 4671) // the copy constructor is inaccessible
+#endif
Added: trunk/boost/interprocess/containers/container/detail/config_end.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/config_end.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,17 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined BOOST_MSVC
+ #pragma warning (pop)
+ #ifdef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
+ #undef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
+ #undef _CRT_SECURE_NO_DEPRECATE
+ #endif
+#endif
+
Added: trunk/boost/interprocess/containers/container/detail/destroyers.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/destroyers.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,154 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
+#define BOOST_CONTAINERS_DESTROYERS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an array of objects using a STL allocator.
+template <class Allocator>
+struct scoped_array_deallocator
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::size_type size_type;
+
+ scoped_array_deallocator(pointer p, Allocator& a, size_type length)
+ : m_ptr(p), m_alloc(a), m_length(length) {}
+
+ ~scoped_array_deallocator()
+ { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
+
+ void release()
+ { m_ptr = 0; }
+
+ private:
+ pointer m_ptr;
+ Allocator& m_alloc;
+ size_type m_length;
+};
+
+template <class Allocator>
+struct null_scoped_array_deallocator
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::size_type size_type;
+
+ null_scoped_array_deallocator(pointer, Allocator&, size_type)
+ {}
+
+ void release()
+ {}
+};
+
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template <class Allocator>
+struct scoped_destructor_n
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::value_type value_type;
+ typedef typename Allocator::size_type size_type;
+
+ pointer m_p;
+ size_type m_n;
+
+ scoped_destructor_n(pointer p, size_type n)
+ : m_p(p), m_n(n)
+ {}
+
+ void release()
+ { m_p = 0; }
+
+ void increment_size(size_type inc)
+ { m_n += inc; }
+
+ ~scoped_destructor_n()
+ {
+ if(!m_p) return;
+ value_type *raw_ptr = containers_detail::get_pointer(m_p);
+ for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr)
+ raw_ptr->~value_type();
+ }
+};
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template <class Allocator>
+struct null_scoped_destructor_n
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::size_type size_type;
+
+ null_scoped_destructor_n(pointer, size_type)
+ {}
+
+ void increment_size(size_type)
+ {}
+
+ void release()
+ {}
+};
+
+template <class A>
+class allocator_destroyer
+{
+ typedef typename A::value_type value_type;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::interprocess_container::containers_detail::
+ version<A>::value> alloc_version;
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+
+ private:
+ A & a_;
+
+ private:
+ void priv_deallocate(const typename A::pointer &p, allocator_v1)
+ { a_.deallocate(p, 1); }
+
+ void priv_deallocate(const typename A::pointer &p, allocator_v2)
+ { a_.deallocate_one(p); }
+
+ public:
+ allocator_destroyer(A &a)
+ : a_(a)
+ {}
+
+ void operator()(const typename A::pointer &p)
+ {
+ containers_detail::get_pointer(p)->~value_type();
+ priv_deallocate(p, alloc_version());
+ }
+};
+
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
Added: trunk/boost/interprocess/containers/container/detail/flat_tree.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/flat_tree.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,837 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
+// permission notice appear in supporting documentation.
+// The author or Addison-Welsey Longman make no representations about the
+// suitability of this software for any purpose. It is provided "as is"
+// without express or implied warranty.
+///////////////////////////////////////////////////////////////////////////////
+//
+// Parts of this file come from AssocVector.h file from Loki library
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_FLAT_TREE_HPP
+#define BOOST_CONTAINERS_FLAT_TREE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/interprocess/detail/move.hpp>
+
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/pair.hpp>
+#include <boost/interprocess/containers/container/vector.hpp>
+#include <boost/interprocess/containers/container/detail/value_init.hpp>
+#include <boost/interprocess/containers/container/detail/destroyers.hpp>
+
+namespace boost {
+
+namespace interprocess_container {
+
+namespace containers_detail {
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+class flat_tree
+{
+ typedef boost::interprocess_container::vector<Value, Alloc> vector_t;
+ typedef Alloc allocator_t;
+
+ public:
+ class value_compare
+ : private Compare
+ {
+ typedef Value first_argument_type;
+ typedef Value second_argument_type;
+ typedef bool return_type;
+ public:
+ value_compare(const Compare &pred)
+ : Compare(pred)
+ {}
+
+ bool operator()(const Value& lhs, const Value& rhs) const
+ {
+ KeyOfValue key_extract;
+ return Compare::operator()(key_extract(lhs), key_extract(rhs));
+ }
+
+ const Compare &get_comp() const
+ { return *this; }
+
+ Compare &get_comp()
+ { return *this; }
+ };
+
+ private:
+ struct Data
+ //Inherit from value_compare to do EBO
+ : public value_compare
+ {
+ public:
+ Data(const Compare &comp,
+ const vector_t &vect)
+ : value_compare(comp), m_vect(vect){}
+
+ Data(const value_compare &comp,
+ const vector_t &vect)
+ : value_compare(comp), m_vect(vect){}
+
+ Data(const Compare &comp,
+ const allocator_t &alloc)
+ : value_compare(comp), m_vect(alloc){}
+ public:
+ vector_t m_vect;
+ };
+
+ Data m_data;
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_tree)
+
+ typedef typename vector_t::value_type value_type;
+ typedef typename vector_t::pointer pointer;
+ typedef typename vector_t::const_pointer const_pointer;
+ typedef typename vector_t::reference reference;
+ typedef typename vector_t::const_reference const_reference;
+ typedef Key key_type;
+ typedef Compare key_compare;
+ typedef typename vector_t::allocator_type allocator_type;
+ typedef allocator_type stored_allocator_type;
+ typedef typename allocator_type::size_type size_type;
+ typedef typename allocator_type::difference_type difference_type;
+ typedef typename vector_t::iterator iterator;
+ typedef typename vector_t::const_iterator const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+
+ // allocation/deallocation
+ flat_tree(const Compare& comp = Compare(),
+ const allocator_type& a = allocator_type())
+ : m_data(comp, a)
+ { }
+
+ flat_tree(const flat_tree& x)
+ : m_data(x.m_data, x.m_data.m_vect)
+ { }
+
+ flat_tree(BOOST_INTERPROCESS_RV_REF(flat_tree) x)
+ : m_data(boost::interprocess::move(x.m_data))
+ { }
+
+ ~flat_tree()
+ { }
+
+ flat_tree& operator=(const flat_tree& x)
+ { m_data = x.m_data; return *this; }
+
+ flat_tree& operator=(BOOST_INTERPROCESS_RV_REF(flat_tree) mx)
+ { m_data = boost::interprocess::move(mx.m_data); return *this; }
+
+ public:
+ // accessors:
+ Compare key_comp() const
+ { return this->m_data.get_comp(); }
+
+ allocator_type get_allocator() const
+ { return this->m_data.m_vect.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->m_data.m_vect.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->m_data.m_vect.get_stored_allocator(); }
+
+ iterator begin()
+ { return this->m_data.m_vect.begin(); }
+
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ const_iterator cbegin() const
+ { return this->m_data.m_vect.begin(); }
+
+ iterator end()
+ { return this->m_data.m_vect.end(); }
+
+ const_iterator end() const
+ { return this->cend(); }
+
+ const_iterator cend() const
+ { return this->m_data.m_vect.end(); }
+
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->end()); }
+
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->cend()); }
+
+ reverse_iterator rend()
+ { return reverse_iterator(this->begin()); }
+
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->cbegin()); }
+
+ bool empty() const
+ { return this->m_data.m_vect.empty(); }
+
+ size_type size() const
+ { return this->m_data.m_vect.size(); }
+
+ size_type max_size() const
+ { return this->m_data.m_vect.max_size(); }
+
+ void swap(flat_tree& other)
+ {
+ value_compare& mycomp = this->m_data;
+ value_compare& othercomp = other.m_data;
+ containers_detail::do_swap(mycomp, othercomp);
+ vector_t & myvect = this->m_data.m_vect;
+ vector_t & othervect = other.m_data.m_vect;
+ myvect.swap(othervect);
+ }
+
+ public:
+ // insert/erase
+ std::pair<iterator,bool> insert_unique(const value_type& val)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, val);
+ }
+ return ret;
+ }
+
+ std::pair<iterator,bool> insert_unique(BOOST_INTERPROCESS_RV_REF(value_type) val)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::interprocess::move(val));
+ }
+ return ret;
+ }
+
+
+ iterator insert_equal(const value_type& val)
+ {
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, val);
+ return i;
+ }
+
+ iterator insert_equal(BOOST_INTERPROCESS_RV_REF(value_type) mval)
+ {
+ iterator i = this->upper_bound(KeyOfValue()(mval));
+ i = this->m_data.m_vect.insert(i, boost::interprocess::move(mval));
+ return i;
+ }
+
+ iterator insert_unique(const_iterator pos, const value_type& val)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, val);
+ }
+ return ret.first;
+ }
+
+ iterator insert_unique(const_iterator pos, BOOST_INTERPROCESS_RV_REF(value_type) mval)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::interprocess::move(mval));
+ }
+ return ret.first;
+ }
+
+ iterator insert_equal(const_iterator pos, const value_type& val)
+ {
+ insert_commit_data data;
+ priv_insert_equal_prepare(pos, val, data);
+ return priv_insert_commit(data, val);
+ }
+
+ iterator insert_equal(const_iterator pos, BOOST_INTERPROCESS_RV_REF(value_type) mval)
+ {
+ insert_commit_data data;
+ priv_insert_equal_prepare(pos, mval, data);
+ return priv_insert_commit(data, boost::interprocess::move(mval));
+ }
+
+ template <class InIt>
+ void insert_unique(InIt first, InIt last)
+ {
+ for ( ; first != last; ++first)
+ this->insert_unique(*first);
+ }
+
+ template <class InIt>
+ void insert_equal(InIt first, InIt last)
+ {
+ typedef typename
+ std::iterator_traits<InIt>::iterator_category ItCat;
+ priv_insert_equal(first, last, ItCat());
+ }
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template <class... Args>
+ iterator emplace_unique(Args&&... args)
+ {
+ value_type val(boost::interprocess::forward<Args>(args)...);
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ template <class... Args>
+ iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ {
+ value_type val(boost::interprocess::forward<Args>(args)...);
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ template <class... Args>
+ iterator emplace_equal(Args&&... args)
+ {
+ value_type val(boost::interprocess::forward<Args>(args)...);
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, boost::interprocess::move<value_type>(val));
+ return i;
+ }
+
+ template <class... Args>
+ iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ {
+ value_type val(boost::interprocess::forward<Args>(args)...);
+ insert_commit_data data;
+ priv_insert_equal_prepare(hint, val, data);
+ return priv_insert_commit(data, boost::interprocess::move<value_type>(val));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace_unique()
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ iterator emplace_hint_unique(const_iterator hint)
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ iterator emplace_equal()
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, boost::interprocess::move<value_type>(val));
+ return i;
+ }
+
+ iterator emplace_hint_equal(const_iterator hint)
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ priv_insert_equal_prepare(hint, val, data);
+ return priv_insert_commit(data, boost::interprocess::move<value_type>(val));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
+ if(ret.second){ \
+ ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val)); \
+ } \
+ return ret.first; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_unique(const_iterator hint, \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
+ if(ret.second){ \
+ ret.first = priv_insert_commit(data, boost::interprocess::move<value_type>(val)); \
+ } \
+ return ret.first; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ iterator i = this->upper_bound(KeyOfValue()(val)); \
+ i = this->m_data.m_vect.insert(i, boost::interprocess::move<value_type>(val)); \
+ return i; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_equal(const_iterator hint, \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ priv_insert_equal_prepare(hint, val, data); \
+ return priv_insert_commit(data, boost::interprocess::move<value_type>(val)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator erase(const_iterator position)
+ { return this->m_data.m_vect.erase(position); }
+
+ size_type erase(const key_type& k)
+ {
+ std::pair<iterator,iterator > itp = this->equal_range(k);
+ size_type ret = static_cast<size_type>(itp.second-itp.first);
+ if (ret){
+ this->m_data.m_vect.erase(itp.first, itp.second);
+ }
+ return ret;
+ }
+
+ iterator erase(const_iterator first, const_iterator last)
+ { return this->m_data.m_vect.erase(first, last); }
+
+ void clear()
+ { this->m_data.m_vect.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { this->m_data.m_vect.shrink_to_fit(); }
+
+ // set operations:
+ iterator find(const key_type& k)
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ iterator i = this->lower_bound(k);
+
+ if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
+ i = this->end();
+ }
+ return i;
+ }
+
+ const_iterator find(const key_type& k) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ const_iterator i = this->lower_bound(k);
+
+ if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
+ i = this->end();
+ }
+ return i;
+ }
+
+ size_type count(const key_type& k) const
+ {
+ std::pair<const_iterator, const_iterator> p = this->equal_range(k);
+ size_type n = p.second - p.first;
+ return n;
+ }
+
+ iterator lower_bound(const key_type& k)
+ { return this->priv_lower_bound(this->begin(), this->end(), k); }
+
+ const_iterator lower_bound(const key_type& k) const
+ { return this->priv_lower_bound(this->begin(), this->end(), k); }
+
+ iterator upper_bound(const key_type& k)
+ { return this->priv_upper_bound(this->begin(), this->end(), k); }
+
+ const_iterator upper_bound(const key_type& k) const
+ { return this->priv_upper_bound(this->begin(), this->end(), k); }
+
+ std::pair<iterator,iterator> equal_range(const key_type& k)
+ { return this->priv_equal_range(this->begin(), this->end(), k); }
+
+ std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
+ { return this->priv_equal_range(this->begin(), this->end(), k); }
+
+ size_type capacity() const
+ { return this->m_data.m_vect.capacity(); }
+
+ void reserve(size_type count)
+ { this->m_data.m_vect.reserve(count); }
+
+ private:
+ struct insert_commit_data
+ {
+ const_iterator position;
+ };
+
+ // insert/erase
+ void priv_insert_equal_prepare
+ (const_iterator pos, const value_type& val, insert_commit_data &data)
+ {
+ // N1780
+ // To insert val at pos:
+ // if pos == end || val <= *pos
+ // if pos == begin || val >= *(pos-1)
+ // insert val before pos
+ // else
+ // insert val before upper_bound(val)
+ // else if pos+1 == end || val <= *(pos+1)
+ // insert val after pos
+ // else
+ // insert val before lower_bound(val)
+ const value_compare &value_comp = this->m_data;
+
+ if(pos == this->cend() || !value_comp(*pos, val)){
+ if (pos == this->cbegin() || !value_comp(val, pos[-1])){
+ data.position = pos;
+ }
+ else{
+ data.position =
+ this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
+ }
+ }
+ //Works, but increases code complexity
+ //else if (++pos == this->end() || !value_comp(*pos, val)){
+ // return this->m_data.m_vect.insert(pos, val);
+ //}
+ else{
+ data.position =
+ this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
+ }
+ }
+
+ std::pair<iterator,bool> priv_insert_unique_prepare
+ (const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
+ {
+ const value_compare &value_comp = this->m_data;
+ commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
+ return std::pair<iterator,bool>
+ ( *reinterpret_cast<iterator*>(&commit_data.position)
+ , commit_data.position == end || value_comp(val, *commit_data.position));
+ }
+
+ std::pair<iterator,bool> priv_insert_unique_prepare
+ (const value_type& val, insert_commit_data &commit_data)
+ { return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
+
+ std::pair<iterator,bool> priv_insert_unique_prepare
+ (const_iterator pos, const value_type& val, insert_commit_data &commit_data)
+ {
+ //N1780. Props to Howard Hinnant!
+ //To insert val at pos:
+ //if pos == end || val <= *pos
+ // if pos == begin || val >= *(pos-1)
+ // insert val before pos
+ // else
+ // insert val before upper_bound(val)
+ //else if pos+1 == end || val <= *(pos+1)
+ // insert val after pos
+ //else
+ // insert val before lower_bound(val)
+ const value_compare &value_comp = this->m_data;
+
+ if(pos == this->cend() || value_comp(val, *pos)){
+ if(pos != this->cbegin() && !value_comp(val, pos[-1])){
+ if(value_comp(pos[-1], val)){
+ commit_data.position = pos;
+ return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
+ }
+ else{
+ return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
+ }
+ }
+ return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
+ }
+
+ // Works, but increases code complexity
+ //Next check
+ //else if (value_comp(*pos, val) && !value_comp(pos[1], val)){
+ // if(value_comp(val, pos[1])){
+ // commit_data.position = pos+1;
+ // return std::pair<iterator,bool>(pos+1, true);
+ // }
+ // else{
+ // return std::pair<iterator,bool>(pos+1, false);
+ // }
+ //}
+ else{
+ //[... pos ... val ... ]
+ //The hint is before the insertion position, so insert it
+ //in the remaining range
+ return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data);
+ }
+ }
+
+ template<class Convertible>
+ iterator priv_insert_commit
+ (insert_commit_data &commit_data, BOOST_INTERPROCESS_FWD_REF(Convertible) convertible)
+ {
+ return this->m_data.m_vect.insert
+ ( commit_data.position
+ , boost::interprocess::forward<Convertible>(convertible));
+ }
+
+ template <class RanIt>
+ RanIt priv_lower_bound(RanIt first, RanIt last,
+ const key_type & key) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ KeyOfValue key_extract;
+ difference_type len = last - first, half;
+ RanIt middle;
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+ middle += half;
+
+ if (key_comp(key_extract(*middle), key)) {
+ ++middle;
+ first = middle;
+ len = len - half - 1;
+ }
+ else
+ len = half;
+ }
+ return first;
+ }
+
+ template <class RanIt>
+ RanIt priv_upper_bound(RanIt first, RanIt last,
+ const key_type & key) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ KeyOfValue key_extract;
+ difference_type len = last - first, half;
+ RanIt middle;
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+ middle += half;
+
+ if (key_comp(key, key_extract(*middle))) {
+ len = half;
+ }
+ else{
+ first = ++middle;
+ len = len - half - 1;
+ }
+ }
+ return first;
+ }
+
+ template <class RanIt>
+ std::pair<RanIt, RanIt>
+ priv_equal_range(RanIt first, RanIt last, const key_type& key) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ KeyOfValue key_extract;
+ difference_type len = last - first, half;
+ RanIt middle, left, right;
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+ middle += half;
+
+ if (key_comp(key_extract(*middle), key)){
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ else if (key_comp(key, key_extract(*middle))){
+ len = half;
+ }
+ else {
+ left = this->priv_lower_bound(first, middle, key);
+ first += len;
+ right = this->priv_upper_bound(++middle, first, key);
+ return std::pair<RanIt, RanIt>(left, right);
+ }
+ }
+ return std::pair<RanIt, RanIt>(first, first);
+ }
+
+ template <class FwdIt>
+ void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = static_cast<size_type>(std::distance(first, last));
+ this->reserve(this->size()+len);
+ this->priv_insert_equal(first, last, std::input_iterator_tag());
+ }
+
+ template <class InIt>
+ void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
+ {
+ for ( ; first != last; ++first)
+ this->insert_equal(*first);
+ }
+
+/*
+ template <class FwdIt>
+ void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = static_cast<size_type>(std::distance(first, last));
+ this->reserve(this->size()+len);
+ priv_insert_unique(first, last, std::input_iterator_tag());
+ }
+
+ template <class InIt>
+ void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag)
+ {
+ for ( ; first != last; ++first)
+ this->insert_unique(*first);
+ }
+*/
+};
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline bool
+operator==(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+{
+ return x.size() == y.size() &&
+ std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline bool
+operator<(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(),
+ y.begin(), y.end());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline bool
+operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+ { return !(x == y); }
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline bool
+operator>(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+ { return y < x; }
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline bool
+operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+ { return !(y < x); }
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline bool
+operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+ { return !(x < y); }
+
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class Alloc>
+inline void
+swap(flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
+ flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
+ { x.swap(y); }
+
+} //namespace containers_detail {
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class V, class KOV,
+class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::containers_detail::flat_tree<K, V, KOV, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_FLAT_TREE_HPP
Added: trunk/boost/interprocess/containers/container/detail/iterators.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/iterators.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,492 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
+#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/detail/move.hpp>
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/interprocess/containers/container/detail/variadic_templates_tools.hpp>
+#else
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+#include <iterator>
+
+namespace boost {
+namespace interprocess_container {
+
+template <class T, class Difference = std::ptrdiff_t>
+class constant_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+ typedef constant_iterator<T, Difference> this_type;
+
+ public:
+ explicit constant_iterator(const T &ref, Difference range_size)
+ : m_ptr(&ref), m_num(range_size){}
+
+ //Constructors
+ constant_iterator()
+ : m_ptr(0), m_num(0){}
+
+ constant_iterator& operator++()
+ { increment(); return *this; }
+
+ constant_iterator operator++(int)
+ {
+ constant_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ constant_iterator& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ constant_iterator operator+(Difference off) const
+ {
+ constant_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend constant_iterator operator+(Difference off, const constant_iterator& right)
+ { return right + off; }
+
+ constant_iterator& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ constant_iterator operator-(Difference off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ private:
+ const T * m_ptr;
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ { return *m_ptr; }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template <class T, class Difference = std::ptrdiff_t>
+class default_construct_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+ typedef default_construct_iterator<T, Difference> this_type;
+
+ public:
+ explicit default_construct_iterator(Difference range_size)
+ : m_num(range_size){}
+
+ //Constructors
+ default_construct_iterator()
+ : m_num(0){}
+
+ default_construct_iterator& operator++()
+ { increment(); return *this; }
+
+ default_construct_iterator operator++(int)
+ {
+ default_construct_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ default_construct_iterator& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ default_construct_iterator operator+(Difference off) const
+ {
+ default_construct_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
+ { return right + off; }
+
+ default_construct_iterator& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ default_construct_iterator operator-(Difference off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ private:
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ {
+ static T dummy;
+ return dummy;
+ }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template <class T, class Difference = std::ptrdiff_t>
+class repeat_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference>
+{
+ typedef repeat_iterator<T, Difference> this_type;
+ public:
+ explicit repeat_iterator(T &ref, Difference range_size)
+ : m_ptr(&ref), m_num(range_size){}
+
+ //Constructors
+ repeat_iterator()
+ : m_ptr(0), m_num(0){}
+
+ this_type& operator++()
+ { increment(); return *this; }
+
+ this_type operator++(int)
+ {
+ this_type result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const this_type& i, const this_type& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const this_type& i, const this_type& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const this_type& i, const this_type& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const this_type& i, const this_type& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const this_type& i, const this_type& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const this_type& i, const this_type& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const this_type& i, const this_type& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ this_type& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ this_type operator+(Difference off) const
+ {
+ this_type other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend this_type operator+(Difference off, const this_type& right)
+ { return right + off; }
+
+ this_type& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ this_type operator-(Difference off) const
+ { return *this + (-off); }
+
+ T& operator*() const
+ { return dereference(); }
+
+ T *operator->() const
+ { return &(dereference()); }
+
+ private:
+ T * m_ptr;
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ T & dereference() const
+ { return *m_ptr; }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template <class T, class E>
+class emplace_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
+{
+ typedef emplace_iterator this_type;
+
+ public:
+ explicit emplace_iterator(E&e)
+ : m_num(1), m_pe(&e){}
+
+ emplace_iterator()
+ : m_num(0), m_pe(0){}
+
+ this_type& operator++()
+ { increment(); return *this; }
+
+ this_type operator++(int)
+ {
+ this_type result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const this_type& i, const this_type& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const this_type& i, const this_type& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const this_type& i, const this_type& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const this_type& i, const this_type& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const this_type& i, const this_type& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const this_type& i, const this_type& i2)
+ { return !(i < i2); }
+
+ friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ this_type& operator+=(std::ptrdiff_t off)
+ { this->advance(off); return *this; }
+
+ this_type operator+(std::ptrdiff_t off) const
+ {
+ this_type other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend this_type operator+(std::ptrdiff_t off, const this_type& right)
+ { return right + off; }
+
+ this_type& operator-=(std::ptrdiff_t off)
+ { this->advance(-off); return *this; }
+
+ this_type operator-(std::ptrdiff_t off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ void construct_in_place(T* ptr)
+ { (*m_pe)(ptr); }
+
+ private:
+ std::ptrdiff_t m_num;
+ E * m_pe;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ {
+ static T dummy;
+ return dummy;
+ }
+
+ void advance(std::ptrdiff_t n)
+ { m_num -= n; }
+
+ std::ptrdiff_t distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+template<class T, class ...Args>
+struct emplace_functor
+{
+ typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+ emplace_functor(Args&&... args)
+ : args_(args...)
+ {}
+
+ void operator()(T *ptr)
+ { emplace_functor::inplace_impl(ptr, index_tuple_t()); }
+
+ template<int ...IdxPack>
+ void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
+ { ::new(ptr) T(boost::interprocess::forward<Args>(containers_detail::get<IdxPack>(args_))...); }
+
+ containers_detail::tuple<Args&&...> args_;
+};
+
+#else
+
+template<class T>
+struct emplace_functor
+{
+ emplace_functor()
+ {}
+ void operator()(T *ptr)
+ { new(ptr) T(); }
+};
+
+#define BOOST_PP_LOCAL_MACRO(n) \
+ template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \
+ struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ { \
+ BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
+ : BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
+ \
+ void operator()(T *ptr) \
+ { \
+ new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ } \
+ BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
+ }; \
+ //!
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#endif
+
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
+
Added: trunk/boost/interprocess/containers/container/detail/mpl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/mpl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,152 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
+#define BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <cstddef>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template <class T, T val>
+struct integral_constant
+{
+ static const T value = val;
+ typedef integral_constant<T,val> type;
+};
+
+template< bool C_ >
+struct bool_ : integral_constant<bool, C_>
+{
+ static const bool value = C_;
+};
+
+typedef bool_<true> true_;
+typedef bool_<false> false_;
+
+typedef true_ true_type;
+typedef false_ false_type;
+
+typedef char yes_type;
+struct no_type
+{
+ char padding[8];
+};
+
+template <bool B, class T = void>
+struct enable_if_c {
+ typedef T type;
+};
+
+template <class T>
+struct enable_if_c<false, T> {};
+
+template <class Cond, class T = void>
+struct enable_if : public enable_if_c<Cond::value, T> {};
+
+template <class Cond, class T = void>
+struct disable_if : public enable_if_c<!Cond::value, T> {};
+
+template <class T, class U>
+class is_convertible
+{
+ typedef char true_t;
+ class false_t { char dummy[2]; };
+ static true_t dispatch(U);
+ static false_t dispatch(...);
+ static T trigger();
+ public:
+ enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+};
+
+template<
+ bool C
+ , typename T1
+ , typename T2
+ >
+struct if_c
+{
+ typedef T1 type;
+};
+
+template<
+ typename T1
+ , typename T2
+ >
+struct if_c<false,T1,T2>
+{
+ typedef T2 type;
+};
+
+template<
+ typename T1
+ , typename T2
+ , typename T3
+ >
+struct if_
+{
+ typedef typename if_c<0 != T1::value, T2, T3>::type type;
+};
+
+
+template <class Pair>
+struct select1st
+// : public std::unary_function<Pair, typename Pair::first_type>
+{
+ template<class OtherPair>
+ const typename Pair::first_type& operator()(const OtherPair& x) const
+ { return x.first; }
+
+ const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
+ { return x; }
+};
+
+// identity is an extension: it is not part of the standard.
+template <class T>
+struct identity
+// : public std::unary_function<T,T>
+{
+ typedef T type;
+ const T& operator()(const T& x) const
+ { return x; }
+};
+
+template<std::size_t S>
+struct ls_zeros
+{
+ static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
+};
+
+template<>
+struct ls_zeros<0>
+{
+ static const std::size_t value = 0;
+};
+
+template<>
+struct ls_zeros<1>
+{
+ static const std::size_t value = 0;
+};
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
+
Added: trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,554 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
+#define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <boost/interprocess/containers/container/detail/transform_iterator.hpp>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template<class VoidPointer>
+class basic_multiallocation_slist
+{
+public:
+ typedef VoidPointer void_pointer;
+
+private:
+ static VoidPointer &priv_get_ref(const VoidPointer &p)
+ { return *static_cast<void_pointer*>(containers_detail::get_pointer(p)); }
+
+ basic_multiallocation_slist(basic_multiallocation_slist &);
+ basic_multiallocation_slist &operator=(basic_multiallocation_slist &);
+
+public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_slist)
+
+ //!This iterator is returned by "allocate_many" functions so that
+ //!the user can access the multiple buffers allocated in a single call
+ class iterator
+ : public std::iterator<std::input_iterator_tag, char>
+ {
+ friend class basic_multiallocation_slist<void_pointer>;
+ void unspecified_bool_type_func() const {}
+ typedef void (iterator::*unspecified_bool_type)() const;
+
+ iterator(void_pointer node_range)
+ : next_node_(node_range)
+ {}
+
+ public:
+ typedef char value_type;
+ typedef value_type & reference;
+ typedef value_type * pointer;
+
+ iterator()
+ : next_node_(0)
+ {}
+
+ iterator &operator=(const iterator &other)
+ { next_node_ = other.next_node_; return *this; }
+
+ public:
+ iterator& operator++()
+ {
+ next_node_ = *static_cast<void_pointer*>(containers_detail::get_pointer(next_node_));
+ return *this;
+ }
+
+ iterator operator++(int)
+ {
+ iterator result(*this);
+ ++*this;
+ return result;
+ }
+
+ bool operator== (const iterator& other) const
+ { return next_node_ == other.next_node_; }
+
+ bool operator!= (const iterator& other) const
+ { return !operator== (other); }
+
+ reference operator*() const
+ { return *static_cast<char*>(containers_detail::get_pointer(next_node_)); }
+
+ operator unspecified_bool_type() const
+ { return next_node_? &iterator::unspecified_bool_type_func : 0; }
+
+ pointer operator->() const
+ { return &(*(*this)); }
+
+ private:
+ void_pointer next_node_;
+ };
+
+private:
+ iterator it_;
+
+public:
+ basic_multiallocation_slist()
+ : it_(iterator())
+ {}
+
+ basic_multiallocation_slist(void_pointer p)
+ : it_(p ? iterator_to(p) : iterator())
+ {}
+
+ basic_multiallocation_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
+ : it_(iterator())
+ { this->swap(other); }
+
+ basic_multiallocation_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
+ {
+ basic_multiallocation_slist tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ bool empty() const
+ { return !it_; }
+
+ iterator before_begin() const
+ { return iterator(void_pointer(const_cast<void*>(static_cast<const void*>(&it_.next_node_)))); }
+
+ iterator begin() const
+ { return it_; }
+
+ iterator end() const
+ { return iterator(); }
+
+ void clear()
+ { this->it_.next_node_ = void_pointer(0); }
+
+ iterator insert_after(iterator it, void_pointer m)
+ {
+ priv_get_ref(m) = priv_get_ref(it.next_node_);
+ priv_get_ref(it.next_node_) = m;
+ return iterator(m);
+ }
+
+ void push_front(void_pointer m)
+ {
+ priv_get_ref(m) = this->it_.next_node_;
+ this->it_.next_node_ = m;
+ }
+
+ void pop_front()
+ { ++it_; }
+
+ void *front() const
+ { return containers_detail::get_pointer(it_.next_node_); }
+
+ void splice_after(iterator after_this, iterator before_begin, iterator before_end)
+ {
+ if (after_this != before_begin && after_this != before_end && before_begin != before_end) {
+ void_pointer next_b = priv_get_ref(before_begin.next_node_);
+ void_pointer next_e = priv_get_ref(before_end.next_node_);
+ void_pointer next_p = priv_get_ref(after_this.next_node_);
+ priv_get_ref(before_begin.next_node_) = next_e;
+ priv_get_ref(before_end.next_node_) = next_p;
+ priv_get_ref(after_this.next_node_) = next_b;
+ }
+ }
+
+ void swap(basic_multiallocation_slist &other_chain)
+ {
+ std::swap(this->it_, other_chain.it_);
+ }
+
+ static iterator iterator_to(void_pointer p)
+ { return iterator(p); }
+
+ void_pointer extract_data()
+ {
+ void_pointer ret = empty() ? void_pointer(0) : void_pointer(&*it_);
+ it_ = iterator();
+ return ret;
+ }
+};
+
+template<class VoidPointer>
+class basic_multiallocation_cached_slist
+{
+private:
+ basic_multiallocation_slist<VoidPointer> slist_;
+ typename basic_multiallocation_slist<VoidPointer>::iterator last_;
+
+ basic_multiallocation_cached_slist(basic_multiallocation_cached_slist &);
+ basic_multiallocation_cached_slist &operator=(basic_multiallocation_cached_slist &);
+
+public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_slist)
+
+ typedef typename basic_multiallocation_slist<VoidPointer>::void_pointer void_pointer;
+ typedef typename basic_multiallocation_slist<VoidPointer>::iterator iterator;
+
+ basic_multiallocation_cached_slist()
+ : slist_(), last_(slist_.before_begin())
+ {}
+ /*
+ basic_multiallocation_cached_slist(iterator first_node)
+ : slist_(first_node), last_(slist_.before_begin())
+ {
+ iterator end;
+ while(first_node != end){
+ ++last_;
+ }
+ }*/
+
+ basic_multiallocation_cached_slist(void_pointer p1, void_pointer p2)
+ : slist_(p1), last_(p2 ? iterator_to(p2) : slist_.before_begin())
+ {}
+
+ basic_multiallocation_cached_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
+ : slist_(), last_(slist_.before_begin())
+ { this->swap(other); }
+
+ basic_multiallocation_cached_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
+ {
+ basic_multiallocation_cached_slist tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ bool empty() const
+ { return slist_.empty(); }
+
+ iterator before_begin() const
+ { return slist_.before_begin(); }
+
+ iterator begin() const
+ { return slist_.begin(); }
+
+ iterator end() const
+ { return slist_.end(); }
+
+ iterator last() const
+ { return last_; }
+
+ void clear()
+ {
+ slist_.clear();
+ last_ = slist_.before_begin();
+ }
+
+ iterator insert_after(iterator it, void_pointer m)
+ {
+ slist_.insert_after(it, m);
+ if(it == last_){
+ last_ = slist_.iterator_to(m);
+ }
+ return iterator_to(m);
+ }
+
+ void push_front(void_pointer m)
+ { this->insert_after(this->before_begin(), m); }
+
+ void push_back(void_pointer m)
+ { this->insert_after(last_, m); }
+
+ void pop_front()
+ {
+ if(last_ == slist_.begin()){
+ last_ = slist_.before_begin();
+ }
+ slist_.pop_front();
+ }
+
+ void *front() const
+ { return slist_.front(); }
+
+ void splice_after(iterator after_this, iterator before_begin, iterator before_end)
+ {
+ if(before_begin == before_end)
+ return;
+ if(after_this == last_){
+ last_ = before_end;
+ }
+ slist_.splice_after(after_this, before_begin, before_end);
+ }
+
+ void swap(basic_multiallocation_cached_slist &x)
+ {
+ slist_.swap(x.slist_);
+ using std::swap;
+ swap(last_, x.last_);
+ if(last_ == x.before_begin()){
+ last_ = this->before_begin();
+ }
+ if(x.last_ == this->before_begin()){
+ x.last_ = x.before_begin();
+ }
+ }
+
+ static iterator iterator_to(void_pointer p)
+ { return basic_multiallocation_slist<VoidPointer>::iterator_to(p); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ {
+ if(this->empty()){
+ return std::pair<void_pointer, void_pointer>(void_pointer(0), void_pointer(0));
+ }
+ else{
+ void_pointer p1 = slist_.extract_data();
+ void_pointer p2 = void_pointer(&*last_);
+ last_ = iterator();
+ return std::pair<void_pointer, void_pointer>(p1, p2);
+ }
+ }
+};
+
+template<class MultiallocatorCachedSlist>
+class basic_multiallocation_cached_counted_slist
+{
+private:
+ MultiallocatorCachedSlist cached_slist_;
+ std::size_t size_;
+
+ basic_multiallocation_cached_counted_slist(basic_multiallocation_cached_counted_slist &);
+ basic_multiallocation_cached_counted_slist &operator=(basic_multiallocation_cached_counted_slist &);
+
+public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_counted_slist)
+
+ typedef typename MultiallocatorCachedSlist::void_pointer void_pointer;
+ typedef typename MultiallocatorCachedSlist::iterator iterator;
+
+ basic_multiallocation_cached_counted_slist()
+ : cached_slist_(), size_(0)
+ {}
+
+ basic_multiallocation_cached_counted_slist(void_pointer p1, void_pointer p2, std::size_t n)
+ : cached_slist_(p1, p2), size_(n)
+ {}
+
+ basic_multiallocation_cached_counted_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
+ : cached_slist_(), size_(0)
+ { this->swap(other); }
+
+ basic_multiallocation_cached_counted_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
+ {
+ basic_multiallocation_cached_counted_slist tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ basic_multiallocation_cached_counted_slist (MultiallocatorCachedSlist mem, std::size_t n)
+ : cached_slist_(boost::interprocess::move(mem)), size_(n)
+ {}
+
+ bool empty() const
+ { return cached_slist_.empty(); }
+
+ std::size_t size() const
+ { return size_; }
+
+ iterator before_begin() const
+ { return cached_slist_.before_begin(); }
+
+ iterator begin() const
+ { return cached_slist_.begin(); }
+
+ iterator end() const
+ { return cached_slist_.end(); }
+
+ iterator last() const
+ { return cached_slist_.last(); }
+
+ void clear()
+ {
+ cached_slist_.clear();
+ size_ = 0;
+ }
+
+ iterator insert_after(iterator it, void_pointer m)
+ {
+ iterator ret = cached_slist_.insert_after(it, m);
+ ++size_;
+ return ret;
+ }
+
+ void push_front(void_pointer m)
+ { this->insert_after(this->before_begin(), m); }
+
+ void push_back(void_pointer m)
+ { this->insert_after(this->before_begin(), m); }
+
+ void pop_front()
+ {
+ cached_slist_.pop_front();
+ --size_;
+ }
+
+ void *front() const
+ { return cached_slist_.front(); }
+
+ void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end)
+ {
+ std::size_t n = static_cast<std::size_t>(std::distance(before_begin, before_end));
+ this->splice_after(after_this, x, before_begin, before_end, n);
+ }
+
+ void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end, std::size_t n)
+ {
+ cached_slist_.splice_after(after_this, before_begin, before_end);
+ size_ += n;
+ x.size_ -= n;
+ }
+
+ void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x)
+ {
+ cached_slist_.splice_after(after_this, x.before_begin(), x.last());
+ size_ += x.size_;
+ x.size_ = 0;
+ }
+
+ void swap(basic_multiallocation_cached_counted_slist &x)
+ {
+ cached_slist_.swap(x.cached_slist_);
+ using std::swap;
+ swap(size_, x.size_);
+ }
+
+ static iterator iterator_to(void_pointer p)
+ { return MultiallocatorCachedSlist::iterator_to(p); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ {
+ size_ = 0;
+ return cached_slist_.extract_data();
+ }
+};
+
+template<class T>
+struct cast_functor
+{
+ typedef typename containers_detail::add_reference<T>::type result_type;
+ result_type operator()(char &ptr) const
+ { return *static_cast<T*>(static_cast<void*>(&ptr)); }
+};
+
+
+template<class MultiallocationChain, class T>
+class transform_multiallocation_chain
+{
+private:
+
+ MultiallocationChain holder_;
+ typedef typename MultiallocationChain::void_pointer void_pointer;
+ typedef typename boost::pointer_to_other
+ <void_pointer, T>::type pointer;
+
+ transform_multiallocation_chain(transform_multiallocation_chain &);
+ transform_multiallocation_chain &operator=(transform_multiallocation_chain &);
+
+ static pointer cast(void_pointer p)
+ {
+ return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
+ }
+
+public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(transform_multiallocation_chain)
+
+ typedef transform_iterator
+ < typename MultiallocationChain::iterator
+ , containers_detail::cast_functor <T> > iterator;
+
+ transform_multiallocation_chain(void_pointer p1, void_pointer p2, std::size_t n)
+ : holder_(p1, p2, n)
+ {}
+
+ transform_multiallocation_chain()
+ : holder_()
+ {}
+
+ transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
+ : holder_()
+ { this->swap(other); }
+
+ transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(MultiallocationChain) other)
+ : holder_(boost::interprocess::move(other))
+ {}
+
+ transform_multiallocation_chain& operator=(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
+ {
+ transform_multiallocation_chain tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ void push_front(pointer mem)
+ { holder_.push_front(mem); }
+
+ void swap(transform_multiallocation_chain &other_chain)
+ { holder_.swap(other_chain.holder_); }
+ /*
+ void splice_after(iterator after_this, iterator before_begin, iterator before_end)
+ { holder_.splice_after(after_this.base(), before_begin.base(), before_end.base()); }
+ */
+ void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
+ { holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
+
+ void pop_front()
+ { holder_.pop_front(); }
+
+ pointer front() const
+ { return cast(holder_.front()); }
+
+ bool empty() const
+ { return holder_.empty(); }
+
+ iterator before_begin() const
+ { return iterator(holder_.before_begin()); }
+
+ iterator begin() const
+ { return iterator(holder_.begin()); }
+
+ iterator end() const
+ { return iterator(holder_.end()); }
+
+ iterator last() const
+ { return iterator(holder_.last()); }
+
+ std::size_t size() const
+ { return holder_.size(); }
+
+ void clear()
+ { holder_.clear(); }
+
+ iterator insert_after(iterator it, pointer m)
+ { return iterator(holder_.insert_after(it.base(), m)); }
+
+ static iterator iterator_to(pointer p)
+ { return iterator(MultiallocationChain::iterator_to(p)); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ { return holder_.extract_data(); }
+
+ MultiallocationChain extract_multiallocation_chain()
+ {
+ return MultiallocationChain(boost::interprocess::move(holder_));
+ }
+};
+
+}}}
+
+// namespace containers_detail {
+// namespace interprocess_container {
+// namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
Added: trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,499 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
+#define BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <utility>
+#include <functional>
+
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/intrusive/options.hpp>
+
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/destroyers.hpp>
+
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an object using a STL allocator.
+template <class Allocator>
+struct scoped_deallocator
+{
+ typedef typename Allocator::pointer pointer;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::interprocess_container::containers_detail::
+ version<Allocator>::value> alloc_version;
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+
+ private:
+ void priv_deallocate(allocator_v1)
+ { m_alloc.deallocate(m_ptr, 1); }
+
+ void priv_deallocate(allocator_v2)
+ { m_alloc.deallocate_one(m_ptr); }
+
+ scoped_deallocator(scoped_deallocator &);
+ scoped_deallocator& operator=(scoped_deallocator &);
+
+ public:
+
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(scoped_deallocator)
+
+ pointer m_ptr;
+ Allocator& m_alloc;
+
+ scoped_deallocator(pointer p, Allocator& a)
+ : m_ptr(p), m_alloc(a)
+ {}
+
+ ~scoped_deallocator()
+ { if (m_ptr)priv_deallocate(alloc_version()); }
+
+ scoped_deallocator(BOOST_INTERPROCESS_RV_REF(scoped_deallocator) o)
+ : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
+ { o.release(); }
+
+ pointer get() const
+ { return m_ptr; }
+
+ void release()
+ { m_ptr = 0; }
+};
+
+template <class A>
+class allocator_destroyer_and_chain_builder
+{
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_chain multiallocation_chain;
+
+ A & a_;
+ multiallocation_chain &c_;
+
+ public:
+ allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
+ : a_(a), c_(c)
+ {}
+
+ void operator()(const typename A::pointer &p)
+ {
+ value_type *vp = containers_detail::get_pointer(p);
+ vp->~value_type();
+ c_.push_front(vp);
+ }
+};
+
+template <class A>
+class allocator_multialloc_chain_node_deallocator
+{
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_chain multiallocation_chain;
+ typedef allocator_destroyer_and_chain_builder<A> chain_builder;
+
+ A & a_;
+ multiallocation_chain c_;
+
+ public:
+ allocator_multialloc_chain_node_deallocator(A &a)
+ : a_(a), c_()
+ {}
+
+ chain_builder get_chain_builder()
+ { return chain_builder(a_, c_); }
+
+ ~allocator_multialloc_chain_node_deallocator()
+ {
+ if(!c_.empty())
+ a_.deallocate_individual(boost::interprocess::move(c_));
+ }
+};
+
+
+template<class ValueCompare, class Node>
+struct node_compare
+ : private ValueCompare
+{
+ typedef typename ValueCompare::key_type key_type;
+ typedef typename ValueCompare::value_type value_type;
+ typedef typename ValueCompare::key_of_value key_of_value;
+
+ node_compare(const ValueCompare &pred)
+ : ValueCompare(pred)
+ {}
+
+ ValueCompare &value_comp()
+ { return static_cast<ValueCompare &>(*this); }
+
+ ValueCompare &value_comp() const
+ { return static_cast<const ValueCompare &>(*this); }
+
+ bool operator()(const Node &a, const Node &b) const
+ { return ValueCompare::operator()(a.get_data(), b.get_data()); }
+};
+
+template<class A, class ICont>
+struct node_alloc_holder
+{
+ typedef node_alloc_holder<A, ICont> self_t;
+ typedef typename A::value_type value_type;
+ typedef typename ICont::value_type Node;
+ typedef typename A::template rebind<Node>::other NodeAlloc;
+ typedef A ValAlloc;
+ typedef typename NodeAlloc::pointer NodePtr;
+ typedef containers_detail::scoped_deallocator<NodeAlloc> Deallocator;
+ typedef typename NodeAlloc::size_type size_type;
+ typedef typename NodeAlloc::difference_type difference_type;
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::interprocess_container::containers_detail::
+ version<NodeAlloc>::value> alloc_version;
+ typedef typename ICont::iterator icont_iterator;
+ typedef typename ICont::const_iterator icont_citerator;
+ typedef allocator_destroyer<NodeAlloc> Destroyer;
+
+ private:
+ node_alloc_holder(node_alloc_holder&);
+ node_alloc_holder & operator=(node_alloc_holder&);
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(node_alloc_holder)
+
+ node_alloc_holder(const ValAlloc &a)
+ : members_(a)
+ {}
+
+ node_alloc_holder(const node_alloc_holder &other)
+ : members_(other.node_alloc())
+ {}
+
+ node_alloc_holder(BOOST_INTERPROCESS_RV_REF(node_alloc_holder) other)
+ : members_(boost::interprocess::move(other.node_alloc()))
+ { this->swap(other); }
+
+ template<class Pred>
+ node_alloc_holder(const ValAlloc &a, const Pred &c)
+ : members_(a, typename ICont::value_compare(c))
+ {}
+
+ template<class Pred>
+ node_alloc_holder(BOOST_INTERPROCESS_RV_REF(ValAlloc) a, const Pred &c)
+ : members_(a, typename ICont::value_compare(c))
+ {}
+
+ template<class Pred>
+ node_alloc_holder(const node_alloc_holder &other, const Pred &c)
+ : members_(other.node_alloc(), typename ICont::value_compare(c))
+ {}
+
+ ~node_alloc_holder()
+ { this->clear(alloc_version()); }
+
+ size_type max_size() const
+ { return this->node_alloc().max_size(); }
+
+ NodePtr allocate_one()
+ { return this->allocate_one(alloc_version()); }
+
+ NodePtr allocate_one(allocator_v1)
+ { return this->node_alloc().allocate(1); }
+
+ NodePtr allocate_one(allocator_v2)
+ { return this->node_alloc().allocate_one(); }
+
+ void deallocate_one(NodePtr p)
+ { return this->deallocate_one(p, alloc_version()); }
+
+ void deallocate_one(NodePtr p, allocator_v1)
+ { this->node_alloc().deallocate(p, 1); }
+
+ void deallocate_one(NodePtr p, allocator_v2)
+ { this->node_alloc().deallocate_one(p); }
+
+ template<class Convertible1, class Convertible2>
+ static void construct(const NodePtr &ptr,
+ #ifdef BOOST_HAS_RVALUE_REFS
+ std::pair<Convertible1, Convertible2> &&
+ #else
+ boost::interprocess::rv<std::pair<Convertible1, Convertible2> > &
+ #endif
+ value)
+ {
+ typedef typename Node::hook_type hook_type;
+ typedef typename Node::value_type::first_type first_type;
+ typedef typename Node::value_type::second_type second_type;
+ Node *nodeptr = containers_detail::get_pointer(ptr);
+
+ //Hook constructor does not throw
+ new(static_cast<hook_type*>(nodeptr))hook_type();
+ //Now construct pair members_holder
+ value_type *valueptr = &nodeptr->get_data();
+ new((void*)&valueptr->first) first_type(boost::interprocess::move(value.first));
+ BOOST_TRY{
+ new((void*)&valueptr->second) second_type(boost::interprocess::move(value.second));
+ }
+ BOOST_CATCH(...){
+ valueptr->first.~first_type();
+ static_cast<hook_type*>(nodeptr)->~hook_type();
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ static void destroy(const NodePtr &ptr)
+ { containers_detail::get_pointer(ptr)->~Node(); }
+
+ Deallocator create_node_and_deallocator()
+ {
+ return Deallocator(this->allocate_one(), this->node_alloc());
+ }
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ static void construct(const NodePtr &ptr, Args &&...args)
+ { new((void*)containers_detail::get_pointer(ptr)) Node(boost::interprocess::forward<Args>(args)...); }
+
+ template<class ...Args>
+ NodePtr create_node(Args &&...args)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ self_t::construct(p, boost::interprocess::forward<Args>(args)...);
+ node_deallocator.release();
+ return (p);
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ static void construct(const NodePtr &ptr)
+ { new((void*)containers_detail::get_pointer(ptr)) Node(); }
+
+ NodePtr create_node()
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ self_t::construct(p);
+ node_deallocator.release();
+ return (p);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ new((void*)containers_detail::get_pointer(ptr)) \
+ Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p = this->allocate_one(); \
+ Deallocator node_deallocator(p, this->node_alloc()); \
+ self_t::construct(p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ node_deallocator.release(); \
+ return (p); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class It>
+ NodePtr create_node_from_it(It it)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ ::boost::interprocess_container::construct_in_place(containers_detail::get_pointer(p), it);
+ node_deallocator.release();
+ return (p);
+ }
+
+ void destroy_node(NodePtr node)
+ {
+ self_t::destroy(node);
+ this->deallocate_one(node);
+ }
+
+ void swap(node_alloc_holder &x)
+ {
+ NodeAlloc& this_alloc = this->node_alloc();
+ NodeAlloc& other_alloc = x.node_alloc();
+
+ if (this_alloc != other_alloc){
+ containers_detail::do_swap(this_alloc, other_alloc);
+ }
+
+ this->icont().swap(x.icont());
+ }
+
+ template<class FwdIterator, class Inserter>
+ FwdIterator allocate_many_and_construct
+ (FwdIterator beg, difference_type n, Inserter inserter)
+ {
+ if(n){
+ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+
+ //Try to allocate memory in a single block
+ multiallocation_chain mem(this->node_alloc().allocate_individual(n));
+ int constructed = 0;
+ Node *p = 0;
+ BOOST_TRY{
+ for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
+ p = containers_detail::get_pointer(mem.front());
+ mem.pop_front();
+ //This can throw
+ constructed = 0;
+ boost::interprocess_container::construct_in_place(p, beg);
+ ++constructed;
+ //This can throw in some containers (predicate might throw)
+ inserter(*p);
+ }
+ }
+ BOOST_CATCH(...){
+ if(constructed){
+ this->destroy(p);
+ }
+ this->node_alloc().deallocate_individual(boost::interprocess::move(mem));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ return beg;
+
+ }
+
+ void clear(allocator_v1)
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+
+ void clear(allocator_v2)
+ {
+ typename NodeAlloc::multiallocation_chain chain;
+ allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
+ this->icont().clear_and_dispose(builder);
+ BOOST_STATIC_ASSERT((boost::interprocess::is_movable<typename NodeAlloc::multiallocation_chain>::value == true));
+ if(!chain.empty())
+ this->node_alloc().deallocate_individual(boost::interprocess::move(chain));
+ }
+
+ icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
+ { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
+
+ icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
+ }
+
+ template<class Key, class Comparator>
+ size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
+ { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
+
+ template<class Key, class Comparator>
+ size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
+ }
+
+ protected:
+ struct cloner
+ {
+ cloner(node_alloc_holder &holder)
+ : m_holder(holder)
+ {}
+
+ NodePtr operator()(const Node &other) const
+ { return m_holder.create_node(other.get_data()); }
+
+ node_alloc_holder &m_holder;
+ };
+
+ struct destroyer
+ {
+ destroyer(node_alloc_holder &holder)
+ : m_holder(holder)
+ {}
+
+ void operator()(NodePtr n) const
+ { m_holder.destroy_node(n); }
+
+ node_alloc_holder &m_holder;
+ };
+
+ struct members_holder
+ : public NodeAlloc
+ {
+ private:
+ members_holder(const members_holder&);
+
+ public:
+ template<class ConvertibleToAlloc>
+ members_holder(const ConvertibleToAlloc &c2alloc)
+ : NodeAlloc(c2alloc)
+ {}
+
+ template<class ConvertibleToAlloc, class Pred>
+ members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
+ : NodeAlloc(c2alloc), m_icont(c)
+ {}
+ //The intrusive container
+ ICont m_icont;
+ } members_;
+
+ ICont &non_const_icont() const
+ { return const_cast<ICont&>(this->members_.m_icont); }
+
+ ICont &icont()
+ { return this->members_.m_icont; }
+
+ const ICont &icont() const
+ { return this->members_.m_icont; }
+
+ NodeAlloc &node_alloc()
+ { return static_cast<NodeAlloc &>(this->members_); }
+
+ const NodeAlloc &node_alloc() const
+ { return static_cast<const NodeAlloc &>(this->members_); }
+};
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
Added: trunk/boost/interprocess/containers/container/detail/pair.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/pair.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,189 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
+#define BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+
+#include <utility> //std::pair
+
+#include <boost/interprocess/detail/move.hpp>
+
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template <class T1, class T2>
+struct pair
+{
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(pair)
+
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ T1 first;
+ T2 second;
+
+ //std::pair compatibility
+ template <class D, class S>
+ pair(const std::pair<D, S>& p)
+ : first(p.first), second(p.second)
+ {}
+
+ //To resolve ambiguity with the variadic constructor of 1 argument
+ //and the previous constructor
+ pair(std::pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
+ template <class D, class S>
+ pair(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ : first(boost::interprocess::move(p.first)), second(boost::interprocess::move(p.second))
+ {}
+
+ pair()
+ : first(), second()
+ {}
+
+ pair(const pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
+ //To resolve ambiguity with the variadic constructor of 1 argument
+ //and the copy constructor
+ pair(pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
+ pair(BOOST_INTERPROCESS_RV_REF(pair) p)
+ : first(boost::interprocess::move(p.first)), second(boost::interprocess::move(p.second))
+ {}
+
+ template <class D, class S>
+ pair(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+ : first(boost::interprocess::move(p.first)), second(boost::interprocess::move(p.second))
+ {}
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class U, class ...Args>
+ pair(U &&u, Args &&... args)
+ : first(boost::interprocess::forward<U>(u))
+ , second(boost::interprocess::forward<Args>(args)...)
+ {}
+
+ #else
+
+ template<class U>
+ pair( BOOST_CONTAINERS_PARAM(U, u)
+ #ifndef BOOST_HAS_RVALUE_REFS
+ , typename containers_detail::disable_if
+ < containers_detail::is_same<U, boost::interprocess::rv<pair> > >::type* = 0
+ #endif
+ )
+ : first(boost::interprocess::forward<U>(const_cast<U&>(u)))
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
+ pair(BOOST_CONTAINERS_PARAM(U, u) \
+ ,BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : first(boost::interprocess::forward<U>(const_cast<U&>(u))) \
+ , second(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+ #endif
+
+ pair& operator=(BOOST_INTERPROCESS_RV_REF(pair) p)
+ {
+ first = boost::interprocess::move(p.first);
+ second = boost::interprocess::move(p.second);
+ return *this;
+ }
+
+ pair& operator=(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ {
+ first = boost::interprocess::move(p.first);
+ second = boost::interprocess::move(p.second);
+ return *this;
+ }
+
+ template <class D, class S>
+ pair& operator=(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ {
+ first = boost::interprocess::move(p.first);
+ second = boost::interprocess::move(p.second);
+ return *this;
+ }
+
+ void swap(pair& p)
+ { std::swap(*this, p); }
+};
+
+template <class T1, class T2>
+inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(x.first == y.first && x.second == y.second); }
+
+template <class T1, class T2>
+inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(x.first < y.first ||
+ (!(y.first < x.first) && x.second < y.second)); }
+
+template <class T1, class T2>
+inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(!(x == y)); }
+
+template <class T1, class T2>
+inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return y < x; }
+
+template <class T1, class T2>
+inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(!(x < y)); }
+
+template <class T1, class T2>
+inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(!(y < x)); }
+
+template <class T1, class T2>
+inline pair<T1, T2> make_pair(T1 x, T2 y)
+{ return pair<T1, T2>(x, y); }
+
+template <class T1, class T2>
+inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
+{
+ swap(x.first, y.first);
+ swap(x.second, y.second);
+}
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_PAIR_HPP
Added: trunk/boost/interprocess/containers/container/detail/preprocessor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/preprocessor.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
+#define BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+#error "This file is not needed when perfect forwarding is available"
+#endif
+
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+
+#define BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS 10
+
+//Note:
+//We define template parameters as const references to
+//be able to bind temporaries. After that we will un-const them.
+//This cast is ugly but it is necessary until "perfect forwarding"
+//is achieved in C++0x. Meanwhile, if we want to be able to
+//bind rvalues with non-const references, we have to be ugly
+#ifdef BOOST_HAS_RVALUE_REFS
+ #define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
+ BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
+ //!
+#else
+ #define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
+ const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
+ //!
+#endif
+
+#ifdef BOOST_HAS_RVALUE_REFS
+ #define BOOST_CONTAINERS_PARAM(U, u) \
+ U && u \
+ //!
+#else
+ #define BOOST_CONTAINERS_PARAM(U, u) \
+ const U & u \
+ //!
+#endif
+
+#ifdef BOOST_HAS_RVALUE_REFS
+#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
+//!
+#else
+#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
+//!
+#endif
+
+#define BOOST_CONTAINERS_AUX_PARAM_INC(z, n, data) \
+ BOOST_PP_CAT(++m_p, n) \
+//!
+
+#ifdef BOOST_HAS_RVALUE_REFS
+#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
+ BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
+//!
+#else
+#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
+ BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
+//!
+#endif
+
+#define BOOST_CONTAINERS_PP_PARAM_FORWARD(z, n, data) \
+boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+//!
+
+#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
+boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
+//!
+
+#define BOOST_CONTAINERS_PP_MEMBER_IT_FORWARD(z, n, data) \
+BOOST_PP_CAT(*m_p, n) \
+//!
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#else
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+#error "This file is not needed when perfect forwarding is available"
+#endif
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
Added: trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,176 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
+#define BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <iterator>
+
+namespace boost {
+namespace interprocess_container {
+
+template <class PseudoReference>
+struct operator_arrow_proxy
+{
+ operator_arrow_proxy(const PseudoReference &px)
+ : m_value(px)
+ {}
+
+ PseudoReference* operator->() const { return &m_value; }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+// operator T*() const { return &m_value; }
+ mutable PseudoReference m_value;
+};
+
+template <class T>
+struct operator_arrow_proxy<T&>
+{
+ operator_arrow_proxy(T &px)
+ : m_value(px)
+ {}
+
+ T* operator->() const { return &m_value; }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+// operator T*() const { return &m_value; }
+ mutable T &m_value;
+};
+
+template <class Iterator, class UnaryFunction>
+class transform_iterator
+ : public UnaryFunction
+ , public std::iterator
+ < typename Iterator::iterator_category
+ , typename containers_detail::remove_reference<typename UnaryFunction::result_type>::type
+ , typename Iterator::difference_type
+ , operator_arrow_proxy<typename UnaryFunction::result_type>
+ , typename UnaryFunction::result_type>
+{
+ public:
+ explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
+ : UnaryFunction(f), m_it(it)
+ {}
+
+ explicit transform_iterator()
+ : UnaryFunction(), m_it()
+ {}
+
+ //Constructors
+ transform_iterator& operator++()
+ { increment(); return *this; }
+
+ transform_iterator operator++(int)
+ {
+ transform_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i == i2); }
+
+/*
+ friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i < i2); }
+*/
+ friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ transform_iterator& operator+=(typename Iterator::difference_type off)
+ { this->advance(off); return *this; }
+
+ transform_iterator operator+(typename Iterator::difference_type off) const
+ {
+ transform_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
+ { return right + off; }
+
+ transform_iterator& operator-=(typename Iterator::difference_type off)
+ { this->advance(-off); return *this; }
+
+ transform_iterator operator-(typename Iterator::difference_type off) const
+ { return *this + (-off); }
+
+ typename UnaryFunction::result_type operator*() const
+ { return dereference(); }
+
+ operator_arrow_proxy<typename UnaryFunction::result_type>
+ operator->() const
+ { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
+
+ Iterator & base()
+ { return m_it; }
+
+ const Iterator & base() const
+ { return m_it; }
+
+ private:
+ Iterator m_it;
+
+ void increment()
+ { ++m_it; }
+
+ void decrement()
+ { --m_it; }
+
+ bool equal(const transform_iterator &other) const
+ { return m_it == other.m_it; }
+
+ bool less(const transform_iterator &other) const
+ { return other.m_it < m_it; }
+
+ typename UnaryFunction::result_type dereference() const
+ { return UnaryFunction::operator()(*m_it); }
+
+ void advance(typename Iterator::difference_type n)
+ { std::advance(m_it, n); }
+
+ typename Iterator::difference_type distance_to(const transform_iterator &other)const
+ { return std::distance(other.m_it, m_it); }
+};
+
+template <class Iterator, class UnaryFunc>
+transform_iterator<Iterator, UnaryFunc>
+make_transform_iterator(Iterator it, UnaryFunc fun)
+{
+ return transform_iterator<Iterator, UnaryFunc>(it, fun);
+}
+
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
Added: trunk/boost/interprocess/containers/container/detail/tree.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/tree.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1018 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_tree file. Modified by Ion Gaztanaga 2005.
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifndef BOOST_CONTAINERS_TREE_HPP
+#define BOOST_CONTAINERS_TREE_HPP
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/intrusive/rbtree.hpp>
+
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+#include <boost/interprocess/containers/container/detail/node_alloc_holder.hpp>
+#include <boost/interprocess/containers/container/detail/destroyers.hpp>
+#include <boost/interprocess/containers/container/detail/pair.hpp>
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+#include <utility> //std::pair
+#include <iterator>
+#include <algorithm>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template<class Key, class Value, class KeyCompare, class KeyOfValue>
+struct value_compare_impl
+ : public KeyCompare
+{
+ typedef Value value_type;
+ typedef KeyCompare key_compare;
+ typedef KeyOfValue key_of_value;
+ typedef Key key_type;
+
+ value_compare_impl(key_compare kcomp)
+ : key_compare(kcomp)
+ {}
+
+ const key_compare &key_comp() const
+ { return static_cast<const key_compare &>(*this); }
+
+ key_compare &key_comp()
+ { return static_cast<key_compare &>(*this); }
+
+ template<class A, class B>
+ bool operator()(const A &a, const B &b) const
+ { return key_compare::operator()(KeyOfValue()(a), KeyOfValue()(b)); }
+};
+
+template<class VoidPointer>
+struct rbtree_hook
+{
+ typedef typename containers_detail::bi::make_set_base_hook
+ < containers_detail::bi::void_pointer<VoidPointer>
+ , containers_detail::bi::link_mode<containers_detail::bi::normal_link>
+ , containers_detail::bi::optimize_size<true>
+ >::type type;
+};
+
+template<class T>
+struct rbtree_type
+{
+ typedef T type;
+};
+
+template<class T1, class T2>
+struct rbtree_type< std::pair<T1, T2> >
+{
+ typedef pair<T1, T2> type;
+};
+
+template <class T, class VoidPointer>
+struct rbtree_node
+ : public rbtree_hook<VoidPointer>::type
+{
+ typedef typename rbtree_hook<VoidPointer>::type hook_type;
+
+ typedef T value_type;
+ typedef typename rbtree_type<T>::type internal_type;
+
+ typedef rbtree_node<T, VoidPointer> node_type;
+
+ #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ rbtree_node()
+ : m_data()
+ {}
+
+ rbtree_node(const rbtree_node &other)
+ : m_data(other.m_data)
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ rbtree_node(Args &&...args)
+ : m_data(boost::interprocess::forward<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ rbtree_node &operator=(const rbtree_node &other)
+ { do_assign(other.m_data); return *this; }
+
+ T &get_data()
+ {
+ T* ptr = reinterpret_cast<T*>(&this->m_data);
+ return *ptr;
+ }
+
+ const T &get_data() const
+ {
+ const T* ptr = reinterpret_cast<const T*>(&this->m_data);
+ return *ptr;
+ }
+
+ private:
+ internal_type m_data;
+
+ template<class A, class B>
+ void do_assign(const std::pair<const A, B> &p)
+ {
+ const_cast<A&>(m_data.first) = p.first;
+ m_data.second = p.second;
+ }
+
+ template<class A, class B>
+ void do_assign(const pair<const A, B> &p)
+ {
+ const_cast<A&>(m_data.first) = p.first;
+ m_data.second = p.second;
+ }
+
+ template<class V>
+ void do_assign(const V &v)
+ { m_data = v; }
+
+ public:
+ template<class Convertible>
+ static void construct(node_type *ptr, BOOST_INTERPROCESS_FWD_REF(Convertible) convertible)
+ { new(ptr) node_type(boost::interprocess::forward<Convertible>(convertible)); }
+};
+
+}//namespace containers_detail {
+#if !defined(BOOST_HAS_RVALUE_REFS)
+template<class T, class VoidPointer>
+struct has_own_construct_from_it
+ < boost::interprocess_container::containers_detail::rbtree_node<T, VoidPointer> >
+{
+ static const bool value = true;
+};
+#endif
+namespace containers_detail {
+
+template<class A, class ValueCompare>
+struct intrusive_rbtree_type
+{
+ typedef typename A::value_type value_type;
+ typedef typename boost::pointer_to_other
+ <typename A::pointer, void>::type void_pointer;
+ typedef typename containers_detail::rbtree_node
+ <value_type, void_pointer> node_type;
+ typedef node_compare<ValueCompare, node_type> node_compare_type;
+ typedef typename containers_detail::bi::make_rbtree
+ <node_type
+ ,containers_detail::bi::compare<node_compare_type>
+ ,containers_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
+ ,containers_detail::bi::constant_time_size<true>
+ ,containers_detail::bi::size_type<typename A::size_type>
+ >::type container_type;
+ typedef container_type type ;
+};
+
+} //namespace containers_detail {
+
+namespace containers_detail {
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+class rbtree
+ : protected containers_detail::node_alloc_holder
+ <A, typename containers_detail::intrusive_rbtree_type
+ <A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue>
+ >::type
+ >
+{
+ typedef typename containers_detail::intrusive_rbtree_type
+ <A, value_compare_impl
+ <Key, Value, KeyCompare, KeyOfValue>
+ >::type Icont;
+ typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef rbtree < Key, Value, KeyOfValue
+ , KeyCompare, A> ThisType;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef typename Icont::iterator iiterator;
+ typedef typename Icont::const_iterator iconst_iterator;
+ typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::allocator_v1 allocator_v1;
+ typedef typename AllocHolder::allocator_v2 allocator_v2;
+ typedef typename AllocHolder::alloc_version alloc_version;
+
+ class RecyclingCloner;
+ friend class RecyclingCloner;
+
+ class RecyclingCloner
+ {
+ public:
+ RecyclingCloner(AllocHolder &holder, Icont &irbtree)
+ : m_holder(holder), m_icont(irbtree)
+ {}
+
+ NodePtr operator()(const Node &other) const
+ {
+// if(!m_icont.empty()){
+ if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
+ //First recycle a node (this can't throw)
+ //NodePtr p = m_icont.unlink_leftmost_without_rebalance();
+ try{
+ //This can throw
+ *p = other;
+ return p;
+ }
+ catch(...){
+ //If there is an exception destroy the whole source
+ m_holder.destroy_node(p);
+ while((p = m_icont.unlink_leftmost_without_rebalance())){
+ m_holder.destroy_node(p);
+ }
+ throw;
+ }
+ }
+ else{
+ return m_holder.create_node(other);
+ }
+ }
+
+ AllocHolder &m_holder;
+ Icont &m_icont;
+ };
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(rbtree)
+
+ typedef Key key_type;
+ typedef Value value_type;
+ typedef A allocator_type;
+ typedef KeyCompare key_compare;
+ typedef value_compare_impl< Key, Value
+ , KeyCompare, KeyOfValue> value_compare;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef typename A::size_type size_type;
+ typedef typename A::difference_type difference_type;
+ typedef difference_type rbtree_difference_type;
+ typedef pointer rbtree_pointer;
+ typedef const_pointer rbtree_const_pointer;
+ typedef reference rbtree_reference;
+ typedef const_reference rbtree_const_reference;
+ typedef NodeAlloc stored_allocator_type;
+
+ private:
+
+ template<class KeyValueCompare>
+ struct key_node_compare
+ : private KeyValueCompare
+ {
+ key_node_compare(KeyValueCompare comp)
+ : KeyValueCompare(comp)
+ {}
+
+ template<class KeyType>
+ bool operator()(const Node &n, const KeyType &k) const
+ { return KeyValueCompare::operator()(n.get_data(), k); }
+
+ template<class KeyType>
+ bool operator()(const KeyType &k, const Node &n) const
+ { return KeyValueCompare::operator()(k, n.get_data()); }
+ };
+
+ typedef key_node_compare<value_compare> KeyNodeCompare;
+
+ public:
+ //rbtree const_iterator
+ class const_iterator
+ : public std::iterator
+ < std::bidirectional_iterator_tag
+ , value_type , rbtree_difference_type
+ , rbtree_const_pointer , rbtree_const_reference>
+ {
+ protected:
+ typedef typename Icont::iterator iiterator;
+ iiterator m_it;
+ explicit const_iterator(iiterator it) : m_it(it){}
+ void prot_incr() { ++m_it; }
+ void prot_decr() { --m_it; }
+
+ private:
+ iiterator get()
+ { return this->m_it; }
+
+ public:
+ friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
+ typedef rbtree_difference_type difference_type;
+
+ //Constructors
+ const_iterator()
+ : m_it()
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return m_it->get_data(); }
+
+ const_pointer operator->() const
+ { return const_pointer(&m_it->get_data()); }
+
+ //Increment / Decrement
+ const_iterator& operator++()
+ { prot_incr(); return *this; }
+
+ const_iterator operator++(int)
+ { iiterator tmp = m_it; ++*this; return const_iterator(tmp); }
+
+ const_iterator& operator--()
+ { prot_decr(); return *this; }
+
+ const_iterator operator--(int)
+ { iiterator tmp = m_it; --*this; return const_iterator(tmp); }
+
+ //Comparison operators
+ bool operator== (const const_iterator& r) const
+ { return m_it == r.m_it; }
+
+ bool operator!= (const const_iterator& r) const
+ { return m_it != r.m_it; }
+ };
+
+ //rbtree iterator
+ class iterator : public const_iterator
+ {
+ private:
+ explicit iterator(iiterator it)
+ : const_iterator(it)
+ {}
+
+ iiterator get()
+ { return this->m_it; }
+
+ public:
+ friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
+ typedef rbtree_pointer pointer;
+ typedef rbtree_reference reference;
+
+ //Constructors
+ iterator(){}
+
+ //Pointer like operators
+ reference operator*() const { return this->m_it->get_data(); }
+ pointer operator->() const { return pointer(&this->m_it->get_data()); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->prot_incr(); return *this; }
+
+ iterator operator++(int)
+ { iiterator tmp = this->m_it; ++*this; return iterator(tmp); }
+
+ iterator& operator--()
+ { this->prot_decr(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp = *this; --*this; return tmp; }
+ };
+
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ rbtree(const key_compare& comp = key_compare(),
+ const allocator_type& a = allocator_type())
+ : AllocHolder(a, comp)
+ {}
+
+ template <class InputIterator>
+ rbtree(InputIterator first, InputIterator last, const key_compare& comp,
+ const allocator_type& a, bool unique_insertion)
+ : AllocHolder(a, comp)
+ {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
+ }
+
+ rbtree(const rbtree& x)
+ : AllocHolder(x, x.key_comp())
+ {
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ }
+
+ rbtree(BOOST_INTERPROCESS_RV_REF(rbtree) x)
+ : AllocHolder(x, x.key_comp())
+ { this->swap(x); }
+
+ ~rbtree()
+ {} //AllocHolder clears the tree
+
+ rbtree& operator=(const rbtree& x)
+ {
+ if (this != &x) {
+ //Transfer all the nodes to a temporary tree
+ //If anything goes wrong, all the nodes will be destroyed
+ //automatically
+ Icont other_tree(this->icont().value_comp());
+ other_tree.swap(this->icont());
+
+ //Now recreate the source tree reusing nodes stored by other_tree
+ this->icont().clone_from
+ (x.icont()
+ , RecyclingCloner(*this, other_tree)
+ //, AllocHolder::cloner(*this)
+ , Destroyer(this->node_alloc()));
+
+ //If there are remaining nodes, destroy them
+ NodePtr p;
+ while((p = other_tree.unlink_leftmost_without_rebalance())){
+ AllocHolder::destroy_node(p);
+ }
+ }
+ return *this;
+ }
+
+ rbtree& operator=(BOOST_INTERPROCESS_RV_REF(rbtree) mx)
+ { this->clear(); this->swap(mx); return *this; }
+
+ public:
+ // accessors:
+ value_compare value_comp() const
+ { return this->icont().value_comp().value_comp(); }
+
+ key_compare key_comp() const
+ { return this->icont().value_comp().value_comp().key_comp(); }
+
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ iterator begin()
+ { return iterator(this->icont().begin()); }
+
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ iterator end()
+ { return iterator(this->icont().end()); }
+
+ const_iterator end() const
+ { return this->cend(); }
+
+ reverse_iterator rbegin()
+ { return reverse_iterator(end()); }
+
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ reverse_iterator rend()
+ { return reverse_iterator(begin()); }
+
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(cend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(cbegin()); }
+
+ bool empty() const
+ { return !this->size(); }
+
+ size_type size() const
+ { return this->icont().size(); }
+
+ size_type max_size() const
+ { return AllocHolder::max_size(); }
+
+ void swap(ThisType& x)
+ { AllocHolder::swap(x); }
+
+ public:
+
+ typedef typename Icont::insert_commit_data insert_commit_data;
+
+ // insert/erase
+ std::pair<iterator,bool> insert_unique_check
+ (const key_type& key, insert_commit_data &data)
+ {
+ std::pair<iiterator, bool> ret =
+ this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
+ return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+ }
+
+ std::pair<iterator,bool> insert_unique_check
+ (const_iterator hint, const key_type& key, insert_commit_data &data)
+ {
+ std::pair<iiterator, bool> ret =
+ this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
+ return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+ }
+
+ iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
+ {
+ NodePtr tmp = AllocHolder::create_node(v);
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
+ return iterator(it);
+ }
+
+ template<class MovableConvertible>
+ iterator insert_unique_commit
+ (BOOST_INTERPROCESS_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
+ {
+ NodePtr tmp = AllocHolder::create_node(boost::interprocess::forward<MovableConvertible>(mv));
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
+ return iterator(it);
+ }
+
+ std::pair<iterator,bool> insert_unique(const value_type& v)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(v), data);
+ if(!ret.second)
+ return ret;
+ return std::pair<iterator,bool>
+ (this->insert_unique_commit(v, data), true);
+ }
+
+ template<class MovableConvertible>
+ std::pair<iterator,bool> insert_unique(BOOST_INTERPROCESS_FWD_REF(MovableConvertible) mv)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(mv), data);
+ if(!ret.second)
+ return ret;
+ return std::pair<iterator,bool>
+ (this->insert_unique_commit(boost::interprocess::forward<MovableConvertible>(mv), data), true);
+ }
+
+ private:
+ iterator emplace_unique_impl(NodePtr p)
+ {
+ value_type &v = p->get_data();
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(v), data);
+ if(!ret.second){
+ Destroyer(this->node_alloc())(p);
+ return ret.first;
+ }
+ return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+ }
+
+ iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
+ {
+ value_type &v = p->get_data();
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(v), data);
+ if(!ret.second){
+ Destroyer(this->node_alloc())(p);
+ return ret.first;
+ }
+ return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+ }
+
+ public:
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template <class... Args>
+ iterator emplace_unique(Args&&... args)
+ { return this->emplace_unique_impl(AllocHolder::create_node(boost::interprocess::forward<Args>(args)...)); }
+
+ template <class... Args>
+ iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::interprocess::forward<Args>(args)...)); }
+
+ template <class... Args>
+ iterator emplace_equal(Args&&... args)
+ {
+ NodePtr p(AllocHolder::create_node(boost::interprocess::forward<Args>(args)...));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ template <class... Args>
+ iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ {
+ NodePtr p(AllocHolder::create_node(boost::interprocess::forward<Args>(args)...));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace_unique()
+ { return this->emplace_unique_impl(AllocHolder::create_node()); }
+
+ iterator emplace_hint_unique(const_iterator hint)
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node()); }
+
+ iterator emplace_equal()
+ {
+ NodePtr p(AllocHolder::create_node());
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ iterator emplace_hint_equal(const_iterator hint)
+ {
+ NodePtr p(AllocHolder::create_node());
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_unique_impl \
+ (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_unique(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_unique_hint_impl \
+ (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_equal(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_equal(hint.get(), *p)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator insert_unique(const_iterator hint, const value_type& v)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(v), data);
+ if(!ret.second)
+ return ret.first;
+ return this->insert_unique_commit(v, data);
+ }
+
+ template<class MovableConvertible>
+ iterator insert_unique(const_iterator hint, BOOST_INTERPROCESS_FWD_REF(MovableConvertible) mv)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(mv), data);
+ if(!ret.second)
+ return ret.first;
+ return this->insert_unique_commit(boost::interprocess::forward<MovableConvertible>(mv), data);
+ }
+
+ template <class InputIterator>
+ void insert_unique(InputIterator first, InputIterator last)
+ {
+ if(this->empty()){
+ //Insert with end hint, to achieve linear
+ //complexity if [first, last) is ordered
+ const_iterator end(this->end());
+ for( ; first != last; ++first)
+ this->insert_unique(end, *first);
+ }
+ else{
+ for( ; first != last; ++first)
+ this->insert_unique(*first);
+ }
+ }
+
+ iterator insert_equal(const value_type& v)
+ {
+ NodePtr p(AllocHolder::create_node(v));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ template<class MovableConvertible>
+ iterator insert_equal(BOOST_INTERPROCESS_FWD_REF(MovableConvertible) mv)
+ {
+ NodePtr p(AllocHolder::create_node(boost::interprocess::forward<MovableConvertible>(mv)));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ iterator insert_equal(const_iterator hint, const value_type& v)
+ {
+ NodePtr p(AllocHolder::create_node(v));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ template<class MovableConvertible>
+ iterator insert_equal(const_iterator hint, BOOST_INTERPROCESS_FWD_REF(MovableConvertible) mv)
+ {
+ NodePtr p(AllocHolder::create_node(boost::interprocess::forward<MovableConvertible>(mv)));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ template <class InputIterator>
+ void insert_equal(InputIterator first, InputIterator last)
+ {
+ //Insert with end hint, to achieve linear
+ //complexity if [first, last) is ordered
+ const_iterator end(this->cend());
+ for( ; first != last; ++first)
+ this->insert_equal(end, *first);
+ }
+
+ iterator erase(const_iterator position)
+ { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
+
+ size_type erase(const key_type& k)
+ { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
+
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
+
+ void clear()
+ { AllocHolder::clear(alloc_version()); }
+
+ // set operations:
+ iterator find(const key_type& k)
+ { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
+
+ const_iterator find(const key_type& k) const
+ { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
+
+ size_type count(const key_type& k) const
+ { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
+
+ iterator lower_bound(const key_type& k)
+ { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
+
+ const_iterator lower_bound(const key_type& k) const
+ { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
+
+ iterator upper_bound(const key_type& k)
+ { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
+
+ const_iterator upper_bound(const key_type& k) const
+ { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
+
+ std::pair<iterator,iterator> equal_range(const key_type& k)
+ {
+ std::pair<iiterator, iiterator> ret =
+ this->icont().equal_range(k, KeyNodeCompare(value_comp()));
+ return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
+ }
+
+ std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
+ {
+ std::pair<iiterator, iiterator> ret =
+ this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
+ return std::pair<const_iterator,const_iterator>
+ (const_iterator(ret.first), const_iterator(ret.second));
+ }
+
+ private:
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (InpIterator beg, InpIterator end, bool unique)
+ {
+ typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(beg, end, unique, alloc_version(), ItCat());
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
+ {
+ if(unique){
+ for (; beg != end; ++beg){
+ this->insert_unique(*beg);
+ }
+ }
+ else{
+ for (; beg != end; ++beg){
+ this->insert_equal(*beg);
+ }
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+
+ public:
+ insertion_functor(Icont &icont)
+ : icont_(icont)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.insert_equal(this->icont_.cend(), n); }
+ };
+
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
+ {
+ if(beg != end){
+ if(unique){
+ priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
+ }
+ else{
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont()));
+ }
+ }
+ }
+};
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
+{
+ return x.size() == y.size() &&
+ std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(),
+ y.begin(), y.end());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return !(x == y);
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return y < x;
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return !(y < x);
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return !(x < y);
+}
+
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline void
+swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
+{
+ x.swap(y);
+}
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class V, class KOV,
+class C, class A>
+struct has_trivial_destructor_after_move
+ <boost::interprocess_container::containers_detail::rbtree<K, V, KOV, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_TREE_HPP
Added: trunk/boost/interprocess/containers/container/detail/type_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/type_traits.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,166 @@
+//////////////////////////////////////////////////////////////////////////////
+// (C) Copyright John Maddock 2000.
+// (C) Copyright Ion Gaztanaga 2005-2008.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+// The alignment_of implementation comes from John Maddock's boost::alignment_of code
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+#define BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+struct nat{};
+
+//boost::alignment_of yields to 10K lines of preprocessed code, so we
+//need an alternative
+template <typename T> struct alignment_of;
+
+template <typename T>
+struct alignment_of_hack
+{
+ char c;
+ T t;
+ alignment_of_hack();
+};
+
+template <unsigned A, unsigned S>
+struct alignment_logic
+{
+ enum{ value = A < S ? A : S };
+};
+
+template< typename T >
+struct alignment_of
+{
+ enum{ value = alignment_logic
+ < sizeof(alignment_of_hack<T>) - sizeof(T)
+ , sizeof(T)>::value };
+};
+
+//This is not standard, but should work with all compilers
+union max_align
+{
+ char char_;
+ short short_;
+ int int_;
+ long long_;
+ #ifdef BOOST_HAS_LONG_LONG
+ long long long_long_;
+ #endif
+ float float_;
+ double double_;
+ long double long_double_;
+ void * void_ptr_;
+};
+
+template<class T>
+struct remove_reference
+{
+ typedef T type;
+};
+
+template<class T>
+struct remove_reference<T&>
+{
+ typedef T type;
+};
+
+template<class T>
+struct is_reference
+{
+ enum { value = false };
+};
+
+template<class T>
+struct is_reference<T&>
+{
+ enum { value = true };
+};
+
+template<class T>
+struct is_pointer
+{
+ enum { value = false };
+};
+
+template<class T>
+struct is_pointer<T*>
+{
+ enum { value = true };
+};
+
+template <typename T>
+struct add_reference
+{
+ typedef T& type;
+};
+
+template<class T>
+struct add_reference<T&>
+{
+ typedef T& type;
+};
+
+template<>
+struct add_reference<void>
+{
+ typedef nat &type;
+};
+
+template<>
+struct add_reference<const void>
+{
+ typedef const nat &type;
+};
+
+template <class T>
+struct add_const_reference
+{ typedef const T &type; };
+
+template <class T>
+struct add_const_reference<T&>
+{ typedef T& type; };
+
+template <typename T, typename U>
+struct is_same
+{
+ typedef char yes_type;
+ struct no_type
+ {
+ char padding[8];
+ };
+
+ template <typename V>
+ static yes_type is_same_tester(V*, V*);
+ static no_type is_same_tester(...);
+
+ static T *t;
+ static U *u;
+
+ static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
+};
+
+} // namespace containers_detail
+} //namespace interprocess_container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
Added: trunk/boost/interprocess/containers/container/detail/utilities.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/utilities.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,95 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
+#define BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <cstdio>
+#include <algorithm>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template <class SizeType>
+SizeType
+ get_next_capacity(const SizeType max_size
+ ,const SizeType capacity
+ ,const SizeType n)
+{
+// if (n > max_size - capacity)
+// throw std::length_error("get_next_capacity");
+
+ const SizeType m3 = max_size/3;
+
+ if (capacity < m3)
+ return capacity + max_value(3*(capacity+1)/5, n);
+
+ if (capacity < m3*2)
+ return capacity + max_value((capacity+1)/2, n);
+
+ return max_size;
+}
+
+template<class T>
+const T &max_value(const T &a, const T &b)
+{ return a > b ? a : b; }
+
+template<class T>
+const T &min_value(const T &a, const T &b)
+{ return a < b ? a : b; }
+
+template<class SmartPtr>
+struct smart_ptr_type
+{
+ typedef typename SmartPtr::value_type value_type;
+ typedef value_type *pointer;
+ static pointer get (const SmartPtr &smartptr)
+ { return smartptr.get();}
+};
+
+template<class T>
+struct smart_ptr_type<T*>
+{
+ typedef T value_type;
+ typedef value_type *pointer;
+ static pointer get (pointer ptr)
+ { return ptr;}
+};
+
+//!Overload for smart pointers to avoid ADL problems with get_pointer
+template<class Ptr>
+inline typename smart_ptr_type<Ptr>::pointer
+get_pointer(const Ptr &ptr)
+{ return smart_ptr_type<Ptr>::get(ptr); }
+
+//!To avoid ADL problems with swap
+template <class T>
+inline void do_swap(T& x, T& y)
+{
+ using std::swap;
+ swap(x, y);
+}
+
+template <std::size_t OrigSize, std::size_t RoundTo>
+struct ct_rounded_size
+{
+ enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
+};
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost {
+
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
Added: trunk/boost/interprocess/containers/container/detail/value_init.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/value_init.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
+#define BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template<class T>
+struct value_init
+{
+ value_init()
+ : m_t()
+ {}
+
+ T m_t;
+};
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
Added: trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,153 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+#define BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <cstddef> //std::size_t
+
+namespace boost {
+namespace interprocess_container {
+namespace containers_detail {
+
+template<typename... Values>
+class tuple;
+
+template<> class tuple<>
+{};
+
+template<typename Head, typename... Tail>
+class tuple<Head, Tail...>
+ : private tuple<Tail...>
+{
+ typedef tuple<Tail...> inherited;
+
+ public:
+ tuple() { }
+
+ // implicit copy-constructor is okay
+ // Construct tuple from separate arguments.
+ tuple(typename add_const_reference<Head>::type v,
+ typename add_const_reference<Tail>::type... vtail)
+ : inherited(vtail...), m_head(v)
+ {}
+
+ // Construct tuple from another tuple.
+ template<typename... VValues>
+ tuple(const tuple<VValues...>& other)
+ : m_head(other.head()), inherited(other.tail())
+ {}
+
+ template<typename... VValues>
+ tuple& operator=(const tuple<VValues...>& other)
+ {
+ m_head = other.head();
+ tail() = other.tail();
+ return this;
+ }
+
+ typename add_reference<Head>::type head() { return m_head; }
+ typename add_reference<const Head>::type head() const { return m_head; }
+
+ inherited& tail() { return *this; }
+ const inherited& tail() const { return *this; }
+
+ protected:
+ Head m_head;
+};
+
+
+template<typename... Values>
+tuple<Values&&...> tie_forward(Values&&... values)
+{ return tuple<Values&&...>(values...); }
+
+template<int I, typename Tuple>
+struct tuple_element;
+
+template<int I, typename Head, typename... Tail>
+struct tuple_element<I, tuple<Head, Tail...> >
+{
+ typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct tuple_element<0, tuple<Head, Tail...> >
+{
+ typedef Head type;
+};
+
+template<int I, typename Tuple>
+class get_impl;
+
+template<int I, typename Head, typename... Values>
+class get_impl<I, tuple<Head, Values...> >
+{
+ typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
+ typedef get_impl<I-1, tuple<Values...> > Next;
+
+ public:
+ typedef typename add_reference<Element>::type type;
+ typedef typename add_const_reference<Element>::type const_type;
+ static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+ static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+};
+
+template<typename Head, typename... Values>
+class get_impl<0, tuple<Head, Values...> >
+{
+ public:
+ typedef typename add_reference<Head>::type type;
+ typedef typename add_const_reference<Head>::type const_type;
+ static type get(tuple<Head, Values...>& t) { return t.head(); }
+ static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
+};
+
+template<int I, typename... Values>
+typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
+{ return get_impl<I, tuple<Values...> >::get(t); }
+
+template<int I, typename... Values>
+typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
+{ return get_impl<I, tuple<Values...> >::get(t); }
+
+////////////////////////////////////////////////////
+// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
+// be used to "unpack" into comma-separated values
+// in a function call.
+////////////////////////////////////////////////////
+
+template<int... Indexes>
+struct index_tuple{};
+
+template<std::size_t Num, typename Tuple = index_tuple<> >
+struct build_number_seq;
+
+template<std::size_t Num, int... Indexes>
+struct build_number_seq<Num, index_tuple<Indexes...> >
+ : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
+{};
+
+template<int... Indexes>
+struct build_number_seq<0, index_tuple<Indexes...> >
+{ typedef index_tuple<Indexes...> type; };
+
+
+}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
Added: trunk/boost/interprocess/containers/container/detail/version_type.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/version_type.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,89 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This code comes from N1953 document by Howard E. Hinnant
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
+#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
+
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+
+
+namespace boost{
+namespace interprocess_container {
+namespace containers_detail {
+
+//using namespace boost;
+
+template <class T, unsigned V>
+struct version_type
+ : public containers_detail::integral_constant<unsigned, V>
+{
+ typedef T type;
+
+ version_type(const version_type<T, 0>&);
+};
+
+namespace impl{
+
+template <class T,
+ bool = containers_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
+struct extract_version
+{
+ static const unsigned value = 1;
+};
+
+template <class T>
+struct extract_version<T, true>
+{
+ static const unsigned value = T::version::value;
+};
+
+template <class T>
+struct has_version
+{
+ private:
+ struct two {char _[2];};
+ template <class U> static two test(...);
+ template <class U> static char test(const typename U::version*);
+ public:
+ static const bool value = sizeof(test<T>(0)) == 1;
+ void dummy(){}
+};
+
+template <class T, bool = has_version<T>::value>
+struct version
+{
+ static const unsigned value = 1;
+};
+
+template <class T>
+struct version<T, true>
+{
+ static const unsigned value = extract_version<T>::value;
+};
+
+} //namespace impl
+
+template <class T>
+struct version
+ : public containers_detail::integral_constant<unsigned, impl::version<T>::value>
+{
+};
+
+} //namespace containers_detail {
+} //namespace interprocess_container {
+} //namespace boost{
+
+#endif //#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
Added: trunk/boost/interprocess/containers/container/detail/workaround.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/workaround.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,24 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
+#define BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)\
+ && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
+#define BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
Added: trunk/boost/interprocess/containers/container/flat_map.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/flat_map.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1390 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_FLAT_MAP_HPP
+#define BOOST_CONTAINERS_FLAT_MAP_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <utility>
+#include <functional>
+#include <memory>
+#include <stdexcept>
+#include <boost/interprocess/containers/container/detail/flat_tree.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/detail/move.hpp>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+// Forward declarations of operators == and <, needed for friend declarations.
+template <class Key, class T, class Pred, class Alloc>
+class flat_map;
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y);
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y);
+/// @endcond
+
+//! A flat_map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another
+//! type T based on the keys. The flat_map class supports random-access iterators.
+//!
+//! A flat_map satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. A flat_map also provides
+//! most operations described for unique keys. For a
+//! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
+//! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! Alloc is the allocator to allocate the value_types
+//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
+//!
+//! flat_map is similar to std::map but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_map invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_map invalidates iterators and references
+//! pointing to elements that come after (their keys are bigger) the erased element.
+template <class Key, class T, class Pred, class Alloc>
+class flat_map
+{
+ /// @cond
+ private:
+ //This is the tree that we should store if pair was movable
+ typedef containers_detail::flat_tree<Key,
+ std::pair<Key, T>,
+ containers_detail::select1st< std::pair<Key, T> >,
+ Pred,
+ Alloc> tree_t;
+
+ //This is the real tree stored here. It's based on a movable pair
+ typedef containers_detail::flat_tree<Key,
+ containers_detail::pair<Key, T>,
+ containers_detail::select1st<containers_detail::pair<Key, T> >,
+ Pred,
+ typename Alloc::template
+ rebind<containers_detail::pair<Key, T> >::other> impl_tree_t;
+ impl_tree_t m_flat_tree; // flat tree representing flat_map
+
+ typedef typename impl_tree_t::value_type impl_value_type;
+ typedef typename impl_tree_t::pointer impl_pointer;
+ typedef typename impl_tree_t::const_pointer impl_const_pointer;
+ typedef typename impl_tree_t::reference impl_reference;
+ typedef typename impl_tree_t::const_reference impl_const_reference;
+ typedef typename impl_tree_t::value_compare impl_value_compare;
+ typedef typename impl_tree_t::iterator impl_iterator;
+ typedef typename impl_tree_t::const_iterator impl_const_iterator;
+ typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
+ typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
+ typedef typename impl_tree_t::allocator_type impl_allocator_type;
+
+ template<class D, class S>
+ static D &force(const S &s)
+ { return *const_cast<D*>(reinterpret_cast<const D*>(&s)); }
+
+ template<class D, class S>
+ static D force_copy(S s)
+ {
+ value_type *vp = reinterpret_cast<value_type *>(&*s);
+ return D(vp);
+ }
+
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_map)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef typename tree_t::value_compare value_compare;
+ typedef T mapped_type;
+ typedef typename tree_t::key_compare key_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! comparison object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit flat_map(const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a)) {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a))
+ { m_flat_tree.insert_unique(first, last); }
+
+ //! <b>Effects</b>: Copy constructs a flat_map.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_map(const flat_map<Key,T,Pred,Alloc>& x)
+ : m_flat_tree(x.m_flat_tree) {}
+
+ //! <b>Effects</b>: Move constructs a flat_map.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_map(BOOST_INTERPROCESS_RV_REF(flat_map) x)
+ : m_flat_tree(boost::interprocess::move(x.m_flat_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_map<Key,T,Pred,Alloc>& operator=(const flat_map<Key, T, Pred, Alloc>& x)
+ { m_flat_tree = x.m_flat_tree; return *this; }
+
+ //! <b>Effects</b>: Move constructs a flat_map.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_map<Key,T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_RV_REF(flat_map) mx)
+ { m_flat_tree = boost::interprocess::move(mx.m_flat_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return force<key_compare>(m_flat_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return force<allocator_type>(m_flat_tree.get_allocator()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return force_copy<iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return force<const_iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return force<const_iterator>(m_flat_tree.cbegin()); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return force_copy<iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return force<const_iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return force<const_iterator>(m_flat_tree.cend()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return force<reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return force<reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return force<const_reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return force<const_reverse_iterator>(m_flat_tree.crend()); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! Effects: If there is no key equivalent to x in the flat_map, inserts
+ //! value_type(x, T()) into the flat_map.
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T &operator[](const key_type& k)
+ {
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first))
+ i = insert(i, value_type(k, T()));
+ return (*i).second;
+ }
+
+ //! Effects: If there is no key equivalent to x in the flat_map, inserts
+ //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T &operator[](BOOST_INTERPROCESS_RV_REF(key_type) mk)
+ {
+ key_type &k = mk;
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first))
+ i = insert(i, value_type(boost::interprocess::move(k), boost::interprocess::move(T())));
+ return (*i).second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ T& at(const key_type& k)
+ {
+ iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ const T& at(const key_type& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_map& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(const value_type& x)
+ { return force<std::pair<iterator,bool> >(
+ m_flat_tree.insert_unique(force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return force<std::pair<iterator,bool> >(
+ m_flat_tree.insert_unique(boost::interprocess::move(force<impl_value_type>(x)))); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(impl_value_type) x)
+ {
+ return force<std::pair<iterator,bool> >
+ (m_flat_tree.insert_unique(boost::interprocess::move(x)));
+ }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, const value_type& x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), boost::interprocess::move(force<impl_value_type>(x)))); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(impl_value_type) x)
+ {
+ return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), boost::interprocess::move(x)));
+ }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_unique(boost::interprocess::forward<Args>(args)...)); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint), boost::interprocess::forward<Args>(args)...)); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return force_copy<iterator>(m_flat_tree.emplace_unique()); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint))); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_unique \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_hint_unique \
+ (force<impl_const_iterator>(hint), \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.s
+ const_iterator find(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
+ { return force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const flat_map<K1, T1, C1, A1>&,
+ const flat_map<K1, T1, C1, A1>&);
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const flat_map<K1, T1, C1, A1>&,
+ const flat_map<K1, T1, C1, A1>&);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator!=(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y)
+ { return !(x == y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y)
+ { return y < x; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<=(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y)
+ { return !(y < x); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>=(const flat_map<Key,T,Pred,Alloc>& x,
+ const flat_map<Key,T,Pred,Alloc>& y)
+ { return !(x < y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline void swap(flat_map<Key,T,Pred,Alloc>& x,
+ flat_map<Key,T,Pred,Alloc>& y)
+ { x.swap(y); }
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::flat_map<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+template <class Key, class T,
+ class Pred,
+ class Alloc>
+class flat_multimap;
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y);
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y);
+/// @endcond
+
+//! A flat_multimap is a kind of associative container that supports equivalent keys
+//! (possibly containing multiple copies of the same key value) and provides for
+//! fast retrieval of values of another type T based on the keys. The flat_multimap
+//! class supports random-access iterators.
+//!
+//! A flat_multimap satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
+//! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! Alloc is the allocator to allocate the value_types
+//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
+template <class Key, class T, class Pred, class Alloc>
+class flat_multimap
+{
+ /// @cond
+ private:
+ typedef containers_detail::flat_tree<Key,
+ std::pair<Key, T>,
+ containers_detail::select1st< std::pair<Key, T> >,
+ Pred,
+ Alloc> tree_t;
+ //This is the real tree stored here. It's based on a movable pair
+ typedef containers_detail::flat_tree<Key,
+ containers_detail::pair<Key, T>,
+ containers_detail::select1st<containers_detail::pair<Key, T> >,
+ Pred,
+ typename Alloc::template
+ rebind<containers_detail::pair<Key, T> >::other> impl_tree_t;
+ impl_tree_t m_flat_tree; // flat tree representing flat_map
+
+ typedef typename impl_tree_t::value_type impl_value_type;
+ typedef typename impl_tree_t::pointer impl_pointer;
+ typedef typename impl_tree_t::const_pointer impl_const_pointer;
+ typedef typename impl_tree_t::reference impl_reference;
+ typedef typename impl_tree_t::const_reference impl_const_reference;
+ typedef typename impl_tree_t::value_compare impl_value_compare;
+ typedef typename impl_tree_t::iterator impl_iterator;
+ typedef typename impl_tree_t::const_iterator impl_const_iterator;
+ typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
+ typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
+ typedef typename impl_tree_t::allocator_type impl_allocator_type;
+
+ template<class D, class S>
+ static D &force(const S &s)
+ { return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
+
+ template<class D, class S>
+ static D force_copy(S s)
+ {
+ value_type *vp = reinterpret_cast<value_type *>(&*s);
+ return D(vp);
+ }
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_multimap)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef typename tree_t::value_compare value_compare;
+ typedef T mapped_type;
+ typedef typename tree_t::key_compare key_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
+ //! object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit flat_multimap(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a)) { }
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_multimap(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a))
+ { m_flat_tree.insert_equal(first, last); }
+
+ //! <b>Effects</b>: Copy constructs a flat_multimap.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multimap(const flat_multimap<Key,T,Pred,Alloc>& x)
+ : m_flat_tree(x.m_flat_tree) { }
+
+ //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_multimap(BOOST_INTERPROCESS_RV_REF(flat_multimap) x)
+ : m_flat_tree(boost::interprocess::move(x.m_flat_tree))
+ { }
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multimap<Key,T,Pred,Alloc>& operator=(const flat_multimap<Key,T,Pred,Alloc>& x)
+ { m_flat_tree = x.m_flat_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ flat_multimap<Key,T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_RV_REF(flat_multimap) mx)
+ { m_flat_tree = boost::interprocess::move(mx.m_flat_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return force<key_compare>(m_flat_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return force<allocator_type>(m_flat_tree.get_allocator()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return force_copy<iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return force<const_iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return force_copy<iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return force<const_iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return force<reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return force<reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return force<const_reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_multimap& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const value_type& x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(boost::interprocess::move(x))); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(BOOST_INTERPROCESS_RV_REF(impl_value_type) x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(boost::interprocess::move(x))); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, const value_type& x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ {
+ return force_copy<iterator>
+ (m_flat_tree.insert_equal(force<impl_const_iterator>(position)
+ , boost::interprocess::move(x)));
+ }
+
+ //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(impl_value_type) x)
+ {
+ return force_copy<iterator>(
+ m_flat_tree.insert_equal(force<impl_const_iterator>(position), boost::interprocess::move(x)));
+ }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) .
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_equal(boost::interprocess::forward<Args>(args)...)); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ {
+ return force_copy<iterator>(m_flat_tree.emplace_hint_equal
+ (force<impl_const_iterator>(hint), boost::interprocess::forward<Args>(args)...));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return force_copy<iterator>(m_flat_tree.emplace_equal()); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_equal(force<impl_const_iterator>(hint))); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_equal \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_hint_equal \
+ (force<impl_const_iterator>(hint), \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: An const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ {return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key
+ //! not less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ {return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key
+ //! not less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& x) const
+ { return force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const flat_multimap<K1, T1, C1, A1>& x,
+ const flat_multimap<K1, T1, C1, A1>& y);
+
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const flat_multimap<K1, T1, C1, A1>& x,
+ const flat_multimap<K1, T1, C1, A1>& y);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator!=(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y)
+ { return !(x == y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y)
+ { return y < x; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<=(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y)
+ { return !(y < x); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>=(const flat_multimap<Key,T,Pred,Alloc>& x,
+ const flat_multimap<Key,T,Pred,Alloc>& y)
+ { return !(x < y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline void swap(flat_multimap<Key,T,Pred,Alloc>& x, flat_multimap<Key,T,Pred,Alloc>& y)
+ { x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move< boost::interprocess_container::flat_multimap<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+} //namespace boost {
+
+/// @endcond
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_FLAT_MAP_HPP */
Added: trunk/boost/interprocess/containers/container/flat_set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/flat_set.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1172 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_FLAT_SET_HPP
+#define BOOST_CONTAINERS_FLAT_SET_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <utility>
+#include <functional>
+#include <memory>
+#include <boost/interprocess/containers/container/detail/flat_tree.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/detail/move.hpp>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+// Forward declarations of operators < and ==, needed for friend declaration.
+
+template <class T, class Pred, class Alloc>
+class flat_set;
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y);
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y);
+/// @endcond
+
+//! flat_set is a Sorted Associative Container that stores objects of type Key.
+//! flat_set is a Simple Associative Container, meaning that its value type,
+//! as well as its key type, is Key. It is also a Unique Associative Container,
+//! meaning that no two elements are the same.
+//!
+//! flat_set is similar to std::set but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_set invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_set invalidates iterators and references
+//! pointing to elements that come after (their keys are bigger) the erased element.
+template <class T, class Pred, class Alloc>
+class flat_set
+{
+ /// @cond
+ private:
+ typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, Alloc> tree_t;
+ tree_t m_flat_tree; // flat tree representing flat_set
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_set)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef typename tree_t::key_compare key_compare;
+ typedef typename tree_t::value_compare value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! comparison object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit flat_set(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_set(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a)
+ { m_flat_tree.insert_unique(first, last); }
+
+ //! <b>Effects</b>: Copy constructs a map.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set(const flat_set<T,Pred,Alloc>& x)
+ : m_flat_tree(x.m_flat_tree) {}
+
+ //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_set(BOOST_INTERPROCESS_RV_REF(flat_set) mx)
+ : m_flat_tree(boost::interprocess::move(mx.m_flat_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set<T,Pred,Alloc>& operator=(const flat_set<T, Pred, Alloc>& x)
+ { m_flat_tree = x.m_flat_tree; return *this; }
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set<T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_RV_REF(flat_set) mx)
+ { m_flat_tree = boost::interprocess::move(mx.m_flat_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_flat_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_flat_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_flat_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_flat_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_flat_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_flat_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_flat_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_set& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(const value_type& x)
+ { return m_flat_tree.insert_unique(x); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_flat_tree.insert_unique(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, const value_type& x)
+ { return m_flat_tree.insert_unique(position, x); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_flat_tree.insert_unique(position, boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_flat_tree.emplace_unique(boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_flat_tree.emplace_hint_unique(hint, boost::interprocess::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_flat_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_flat_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return m_flat_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_flat_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.s
+ const_iterator find(const key_type& x) const
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
+
+ template <class K1, class C1, class A1>
+ friend bool operator< (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
+ /// @endcond
+};
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator!=(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y)
+ { return !(x == y); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y)
+ { return y < x; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<=(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y)
+ { return !(y < x); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>=(const flat_set<T,Pred,Alloc>& x,
+ const flat_set<T,Pred,Alloc>& y)
+ { return !(x < y); }
+
+template <class T, class Pred, class Alloc>
+inline void swap(flat_set<T,Pred,Alloc>& x, flat_set<T,Pred,Alloc>& y)
+ { x.swap(y); }
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::flat_set<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value &&has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template <class T, class Pred, class Alloc>
+class flat_multiset;
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y);
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y);
+/// @endcond
+
+//! flat_multiset is a Sorted Associative Container that stores objects of type Key.
+//! flat_multiset is a Simple Associative Container, meaning that its value type,
+//! as well as its key type, is Key.
+//! flat_Multiset can store multiple copies of the same key value.
+//!
+//! flat_multiset is similar to std::multiset but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_multiset invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_multiset invalidates iterators and references
+//! pointing to elements that come after (their keys are equal or bigger) the erased element.
+template <class T, class Pred, class Alloc>
+class flat_multiset
+{
+ /// @cond
+ private:
+ typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, Alloc> tree_t;
+ tree_t m_flat_tree; // flat tree representing flat_multiset
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_multiset)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef typename tree_t::key_compare key_compare;
+ typedef typename tree_t::value_compare value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ // allocation/deallocation
+ explicit flat_multiset(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a) {}
+
+ template <class InputIterator>
+ flat_multiset(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a)
+ { m_flat_tree.insert_equal(first, last); }
+
+ flat_multiset(const flat_multiset<T,Pred,Alloc>& x)
+ : m_flat_tree(x.m_flat_tree) {}
+
+ flat_multiset(BOOST_INTERPROCESS_RV_REF(flat_multiset) x)
+ : m_flat_tree(boost::interprocess::move(x.m_flat_tree))
+ {}
+
+ flat_multiset<T,Pred,Alloc>& operator=(const flat_multiset<T,Pred,Alloc>& x)
+ { m_flat_tree = x.m_flat_tree; return *this; }
+
+ flat_multiset<T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_RV_REF(flat_multiset) mx)
+ { m_flat_tree = boost::interprocess::move(mx.m_flat_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_flat_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_flat_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_flat_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_flat_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_flat_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_flat_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_flat_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_multiset& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const value_type& x)
+ { return m_flat_tree.insert_equal(x); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from x
+ //! and returns the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_flat_tree.insert_equal(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, const value_type& x)
+ { return m_flat_tree.insert_equal(position, x); }
+
+ //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_flat_tree.insert_equal(position, boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) .
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_flat_tree.emplace_equal(boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_flat_tree.emplace_hint_equal(hint, boost::interprocess::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_flat_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_flat_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return m_flat_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_flat_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.s
+ const_iterator find(const key_type& x) const
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const flat_multiset<K1,C1,A1>&,
+ const flat_multiset<K1,C1,A1>&);
+ template <class K1, class C1, class A1>
+ friend bool operator< (const flat_multiset<K1,C1,A1>&,
+ const flat_multiset<K1,C1,A1>&);
+ /// @endcond
+};
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator!=(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y)
+ { return !(x == y); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y)
+ { return y < x; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<=(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y)
+ { return !(y < x); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>=(const flat_multiset<T,Pred,Alloc>& x,
+ const flat_multiset<T,Pred,Alloc>& y)
+{ return !(x < y); }
+
+template <class T, class Pred, class Alloc>
+inline void swap(flat_multiset<T,Pred,Alloc>& x, flat_multiset<T,Pred,Alloc>& y)
+ { x.swap(y); }
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::flat_multiset<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+/// @endcond
+
+}}
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_FLAT_SET_HPP */
Added: trunk/boost/interprocess/containers/container/list.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/list.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1372 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_list.h file. Modified by Ion Gaztanaga 2004
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_CONTAINERS_LIST_HPP_
+#define BOOST_CONTAINERS_LIST_HPP_
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/intrusive/list.hpp>
+#include <boost/interprocess/containers/container/detail/node_alloc_holder.hpp>
+
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+//Preprocessor library to emulate perfect forwarding
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+#include <iterator>
+#include <utility>
+#include <memory>
+#include <functional>
+#include <algorithm>
+#include <stdexcept>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+namespace containers_detail {
+
+template<class VoidPointer>
+struct list_hook
+{
+ typedef typename containers_detail::bi::make_list_base_hook
+ <containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
+};
+
+template <class T, class VoidPointer>
+struct list_node
+ : public list_hook<VoidPointer>::type
+{
+
+ #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ list_node()
+ : m_data()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ list_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ list_node(Args &&...args)
+ : m_data(boost::interprocess::forward<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ T m_data;
+};
+
+template<class A>
+struct intrusive_list_type
+{
+ typedef typename A::value_type value_type;
+ typedef typename boost::pointer_to_other
+ <typename A::pointer, void>::type void_pointer;
+ typedef typename containers_detail::list_node
+ <value_type, void_pointer> node_type;
+ typedef typename containers_detail::bi::make_list
+ < node_type
+ , containers_detail::bi::base_hook<typename list_hook<void_pointer>::type>
+ , containers_detail::bi::constant_time_size<true>
+ , containers_detail::bi::size_type<typename A::size_type>
+ >::type container_type;
+ typedef container_type type ;
+};
+
+} //namespace containers_detail {
+/// @endcond
+
+//! A list is a doubly linked list. That is, it is a Sequence that supports both
+//! forward and backward traversal, and (amortized) constant time insertion and
+//! removal of elements at the beginning or the end, or in the middle. Lists have
+//! the important property that insertion and splicing do not invalidate iterators
+//! to list elements, and that even removal invalidates only the iterators that point
+//! to the elements that are removed. The ordering of iterators may be changed
+//! (that is, list<T>::iterator might have a different predecessor or successor
+//! after a list operation than it did before), but the iterators themselves will
+//! not be invalidated or made to point to different elements unless that invalidation
+//! or mutation is explicit.
+template <class T, class A>
+class list
+ : protected containers_detail::node_alloc_holder
+ <A, typename containers_detail::intrusive_list_type<A>::type>
+{
+ /// @cond
+ typedef typename
+ containers_detail::intrusive_list_type<A>::type Icont;
+ typedef list <T, A> ThisType;
+ typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::allocator_v1 allocator_v1;
+ typedef typename AllocHolder::allocator_v2 allocator_v2;
+ typedef typename AllocHolder::alloc_version alloc_version;
+
+ class equal_to_value
+ {
+ typedef typename AllocHolder::value_type value_type;
+ const value_type &t_;
+
+ public:
+ equal_to_value(const value_type &t)
+ : t_(t)
+ {}
+
+ bool operator()(const value_type &t)const
+ { return t_ == t; }
+ };
+
+ template<class Pred>
+ struct ValueCompareToNodeCompare
+ : Pred
+ {
+ ValueCompareToNodeCompare(Pred pred)
+ : Pred(pred)
+ {}
+
+ bool operator()(const Node &a, const Node &b) const
+ { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
+
+ bool operator()(const Node &a) const
+ { return static_cast<const Pred&>(*this)(a.m_data); }
+ };
+ /// @endcond
+
+ public:
+ //! The type of object, T, stored in the list
+ typedef T value_type;
+ //! Pointer to T
+ typedef typename A::pointer pointer;
+ //! Const pointer to T
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to T
+ typedef typename A::reference reference;
+ //! Const reference to T
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! The allocator type
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef NodeAlloc stored_allocator_type;
+
+ /// @cond
+ private:
+ typedef difference_type list_difference_type;
+ typedef pointer list_pointer;
+ typedef const_pointer list_const_pointer;
+ typedef reference list_reference;
+ typedef const_reference list_const_reference;
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(list)
+
+ //! Const iterator used to iterate through a list.
+ class const_iterator
+ /// @cond
+ : public std::iterator<std::bidirectional_iterator_tag,
+ value_type, list_difference_type,
+ list_const_pointer, list_const_reference>
+ {
+
+ protected:
+ typename Icont::iterator m_it;
+ explicit const_iterator(typename Icont::iterator it) : m_it(it){}
+ void prot_incr() { ++m_it; }
+ void prot_decr() { --m_it; }
+
+ private:
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class list<T, A>;
+ typedef list_difference_type difference_type;
+
+ //Constructors
+ const_iterator()
+ : m_it()
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return m_it->m_data; }
+
+ const_pointer operator->() const
+ { return const_pointer(&m_it->m_data); }
+
+ //Increment / Decrement
+ const_iterator& operator++()
+ { prot_incr(); return *this; }
+
+ const_iterator operator++(int)
+ { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
+
+ const_iterator& operator--()
+ { prot_decr(); return *this; }
+
+ const_iterator operator--(int)
+ { typename Icont::iterator tmp = m_it; --*this; return const_iterator(tmp); }
+
+ //Comparison operators
+ bool operator== (const const_iterator& r) const
+ { return m_it == r.m_it; }
+
+ bool operator!= (const const_iterator& r) const
+ { return m_it != r.m_it; }
+ }
+ /// @endcond
+ ;
+
+ //! Iterator used to iterate through a list
+ class iterator
+ /// @cond
+ : public const_iterator
+ {
+
+ private:
+ explicit iterator(typename Icont::iterator it)
+ : const_iterator(it)
+ {}
+
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class list<T, A>;
+ typedef list_pointer pointer;
+ typedef list_reference reference;
+
+ //Constructors
+ iterator(){}
+
+ //Pointer like operators
+ reference operator*() const { return this->m_it->m_data; }
+ pointer operator->() const { return pointer(&this->m_it->m_data); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->prot_incr(); return *this; }
+
+ iterator operator++(int)
+ { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
+
+ iterator& operator--()
+ { this->prot_decr(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp = *this; --*this; return tmp; }
+ };
+ /// @endcond
+
+ //! Iterator used to iterate backwards through a list.
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ //! Const iterator used to iterate backwards through a list.
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit list(const allocator_type &a = A())
+ : AllocHolder(a)
+ {}
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ list(size_type n)
+ : AllocHolder(A())
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ list(size_type n, const T& value, const A& a = A())
+ : AllocHolder(a)
+ { this->insert(this->cbegin(), n, value); }
+
+ //! <b>Effects</b>: Copy constructs a list.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ list(const list& x)
+ : AllocHolder(x)
+ { this->insert(this->cbegin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ list(BOOST_INTERPROCESS_RV_REF(list) x)
+ : AllocHolder(boost::interprocess::move((AllocHolder&)x))
+ {}
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the list.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InpIt>
+ list(InpIt first, InpIt last, const A &a = A())
+ : AllocHolder(a)
+ { this->insert(this->cbegin(), first, last); }
+
+ //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~list()
+ {} //AllocHolder clears the list
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ //! <b>Effects</b>: Erases all the elements of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the list.
+ void clear()
+ { AllocHolder::clear(alloc_version()); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return iterator(this->icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return iterator(this->icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(begin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->cend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->cbegin()); }
+
+ //! <b>Effects</b>: Returns true if the list contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->size(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->icont().size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return AllocHolder::max_size(); }
+
+ //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(const T& x)
+ { this->insert(this->cbegin(), x); }
+
+ //! <b>Effects</b>: Constructs a new element in the beginning of the list
+ //! and moves the resources of t to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(BOOST_INTERPROCESS_RV_REF(T) x)
+ { this->insert(this->cbegin(), boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Removes the last element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back (const T& x)
+ { this->insert(this->cend(), x); }
+
+ //! <b>Effects</b>: Removes the first element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back (BOOST_INTERPROCESS_RV_REF(T) x)
+ { this->insert(this->cend(), boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Removes the first element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void pop_front()
+ { this->erase(this->cbegin()); }
+
+ //! <b>Effects</b>: Removes the last element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void pop_back()
+ { const_iterator tmp = this->cend(); this->erase(--tmp); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return *this->begin(); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->begin(); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back()
+ { return *(--this->end()); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back() const
+ { return *(--this->end()); }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ const_iterator iend = this->cend();
+ size_type len = this->size();
+
+ if(len > new_size){
+ size_type to_erase = len - new_size;
+ while(to_erase--){
+ --iend;
+ }
+ this->erase(iend, this->cend());
+ }
+ else{
+ this->priv_create_and_insert_nodes(iend, new_size - len, x);
+ }
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ const_iterator iend = this->end();
+ size_type len = this->size();
+
+ if(len > new_size){
+ size_type to_erase = len - new_size;
+ const_iterator ifirst;
+ if(to_erase < len/2u){
+ ifirst = iend;
+ while(to_erase--){
+ --ifirst;
+ }
+ }
+ else{
+ ifirst = this->begin();
+ size_type to_skip = len - to_erase;
+ while(to_skip--){
+ ++ifirst;
+ }
+ }
+ this->erase(ifirst, iend);
+ }
+ else{
+ this->priv_create_and_insert_nodes(this->cend(), new_size - len);
+ }
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(ThisType& x)
+ { AllocHolder::swap(x); }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ ThisType& operator=(const ThisType& x)
+ {
+ if (this != &x) {
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ ThisType& operator=(BOOST_INTERPROCESS_RV_REF(ThisType) mx)
+ {
+ this->clear();
+ this->swap(mx);
+ return *this;
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void insert(const_iterator p, size_type n, const T& x)
+ { this->priv_create_and_insert_nodes(p, n, x); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last).
+ template <class InpIt>
+ void insert(const_iterator p, InpIt first, InpIt last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(p, first, last, Result());
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator insert(const_iterator p, const T& x)
+ {
+ NodePtr tmp = AllocHolder::create_node(x);
+ return iterator(this->icont().insert(p.get(), *tmp));
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator insert(const_iterator p, BOOST_INTERPROCESS_RV_REF(T) x)
+ {
+ NodePtr tmp = AllocHolder::create_node(boost::interprocess::move(x));
+ return iterator(this->icont().insert(p.get(), *tmp));
+ }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ {
+ this->emplace(this->cend(), boost::interprocess::forward<Args>(args)...);
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ {
+ this->emplace(this->cbegin(), boost::interprocess::forward<Args>(args)...);
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node(boost::interprocess::forward<Args>(args)...);
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert(p.get(), *node));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_back()
+ { this->emplace(this->cend()); }
+
+ void emplace_front()
+ { this->emplace(this->cbegin()); }
+
+ iterator emplace(const_iterator p)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node();
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert(p.get(), *node));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace(this->cend(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { this->emplace(this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));} \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
+ new ((void*)containers_detail::get_pointer(d.get())) \
+ Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ NodePtr node = d.get(); \
+ d.release(); \
+ return iterator(this->icont().insert(p.get(), *node)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Erases the element at p p.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator erase(const_iterator p)
+ { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
+
+ //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+ //!
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InpIt>
+ void assign(InpIt first, InpIt last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(iterator p, ThisType& x)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont());
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType &x, const_iterator i)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont(), i.get());
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements transferred.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont(), first.get(), last.get());
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //! n == std::distance(first, last)
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Effects</b>: Reverses the order of elements in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time.
+ //!
+ //! <b>Note</b>: Iterators and references are not invalidated
+ void reverse()
+ { this->icont().reverse(); }
+
+ //! <b>Effects</b>: Removes all the elements that compare equal to value.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void remove(const T& value)
+ { remove_if(equal_to_value(value)); }
+
+ //! <b>Effects</b>: Removes all the elements for which a specified
+ //! predicate is satisfied.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class Pred>
+ void remove_if(Pred pred)
+ {
+ typedef ValueCompareToNodeCompare<Pred> Predicate;
+ this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that are equal from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void unique()
+ { this->unique(value_equal()); }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that satisfy some binary predicate from the list.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class BinaryPredicate>
+ void unique(BinaryPredicate binary_pred)
+ {
+ typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
+ this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Requires</b>: The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this according to std::less<value_type>. The merge is stable;
+ //! that is, if an element from *this is equivalent to one from x, then the element
+ //! from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ void merge(list<T, A>& x)
+ { this->merge(x, value_less()); }
+
+ //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+ //! ordering and both *this and x must be sorted according to that ordering
+ //! The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this. The merge is stable; that is, if an element from *this is
+ //! equivalent to one from x, then the element from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ //!
+ //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ template <class StrictWeakOrdering>
+ void merge(list &x, StrictWeakOrdering comp)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+ else{
+ throw std::runtime_error("list::merge called with unequal allocators");
+ }
+ }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ void sort()
+ { this->sort(value_less()); }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ template <class StrictWeakOrdering>
+ void sort(StrictWeakOrdering comp)
+ {
+ // nothing if the list has length 0 or 1.
+ if (this->size() < 2)
+ return;
+ this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+
+ /// @cond
+ private:
+
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, InpIterator beg, InpIterator end)
+ {
+ typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(pos, beg, end, alloc_version(), ItCat());
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+ {
+ for (; beg != end; ++beg){
+ this->icont().insert(pos.get(), *this->create_node_from_it(beg));
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+ typename Icont::const_iterator pos_;
+
+ public:
+ insertion_functor(Icont &icont, typename Icont::const_iterator pos)
+ : icont_(icont), pos_(pos)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.insert(pos_, n); }
+ };
+
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ if(beg != end){
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
+ }
+ }
+
+ //Default constructed version
+ void priv_create_and_insert_nodes(const_iterator pos, size_type n)
+ {
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->priv_create_and_insert_nodes(pos, default_iterator(n), default_iterator());
+ }
+
+ //Copy constructed version
+ void priv_create_and_insert_nodes(const_iterator pos, size_type n, const T& x)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->priv_create_and_insert_nodes(pos, cvalue_iterator(x, n), cvalue_iterator());
+ }
+
+ //Dispatch to detect iterator range or integer overloads
+ template <class InputIter>
+ void priv_insert_dispatch(const_iterator p,
+ InputIter first, InputIter last,
+ containers_detail::false_)
+ { this->priv_create_and_insert_nodes(p, first, last); }
+
+ template<class Integer>
+ void priv_insert_dispatch(const_iterator p, Integer n, Integer x, containers_detail::true_)
+ { this->insert(p, (size_type)n, x); }
+
+ void priv_fill_assign(size_type n, const T& val)
+ {
+ iterator i = this->begin(), iend = this->end();
+
+ for ( ; i != iend && n > 0; ++i, --n)
+ *i = val;
+ if (n > 0){
+ this->priv_create_and_insert_nodes(this->cend(), n, val);
+ }
+ else{
+ this->erase(i, cend());
+ }
+ }
+
+ template <class Integer>
+ void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
+ { this->priv_fill_assign((size_type) n, (T) val); }
+
+ template <class InputIter>
+ void priv_assign_dispatch(InputIter first2, InputIter last2, containers_detail::false_)
+ {
+ iterator first1 = this->begin();
+ iterator last1 = this->end();
+ for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+ *first1 = *first2;
+ if (first2 == last2)
+ this->erase(first1, last1);
+ else{
+ this->priv_create_and_insert_nodes(last1, first2, last2);
+ }
+ }
+
+ //Functors for member algorithm defaults
+ struct value_less
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a < b; }
+ };
+
+ struct value_equal
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a == b; }
+ };
+ /// @endcond
+
+};
+
+template <class T, class A>
+inline bool operator==(const list<T,A>& x, const list<T,A>& y)
+{
+ if(x.size() != y.size()){
+ return false;
+ }
+ typedef typename list<T,A>::const_iterator const_iterator;
+ const_iterator end1 = x.end();
+
+ const_iterator i1 = x.begin();
+ const_iterator i2 = y.begin();
+ while (i1 != end1 && *i1 == *i2) {
+ ++i1;
+ ++i2;
+ }
+ return i1 == end1;
+}
+
+template <class T, class A>
+inline bool operator<(const list<T,A>& x,
+ const list<T,A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T, class A>
+inline bool operator!=(const list<T,A>& x, const list<T,A>& y)
+{
+ return !(x == y);
+}
+
+template <class T, class A>
+inline bool operator>(const list<T,A>& x, const list<T,A>& y)
+{
+ return y < x;
+}
+
+template <class T, class A>
+inline bool operator<=(const list<T,A>& x, const list<T,A>& y)
+{
+ return !(y < x);
+}
+
+template <class T, class A>
+inline bool operator>=(const list<T,A>& x, const list<T,A>& y)
+{
+ return !(x < y);
+}
+
+template <class T, class A>
+inline void swap(list<T, A>& x, list<T, A>& y)
+{
+ x.swap(y);
+}
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::list<T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+/// @endcond
+
+}}
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_LIST_HPP_
Added: trunk/boost/interprocess/containers/container/map.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/map.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1266 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_map/stl_multimap files. Modified by Ion Gaztanaga.
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_CONTAINERS_MAP_HPP
+#define BOOST_CONTAINERS_MAP_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <utility>
+#include <functional>
+#include <memory>
+#include <stdexcept>
+#include <boost/interprocess/containers/container/detail/tree.hpp>
+#include <boost/interprocess/containers/container/detail/value_init.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/pair.hpp>
+#include <boost/interprocess/detail/move.hpp>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+// Forward declarations of operators == and <, needed for friend declarations.
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y);
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y);
+/// @endcond
+
+//! A map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another
+//! type T based on the keys. The map class supports bidirectional iterators.
+//!
+//! A map satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! Alloc is the allocator to allocate the value_types
+//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
+template <class Key, class T, class Pred, class Alloc>
+class map
+{
+ /// @cond
+ private:
+ typedef containers_detail::rbtree<Key,
+ std::pair<const Key, T>,
+ containers_detail::select1st< std::pair<const Key, T> >,
+ Pred,
+ Alloc> tree_t;
+ tree_t m_tree; // red-black tree representing map
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(map)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef T mapped_type;
+ typedef Pred key_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+ typedef std::pair<key_type, mapped_type> nonconst_value_type;
+ typedef containers_detail::pair
+ <key_type, mapped_type> nonconst_impl_value_type;
+
+ /// @cond
+ class value_compare_impl
+ : public Pred,
+ public std::binary_function<value_type, value_type, bool>
+ {
+ friend class map<Key,T,Pred,Alloc>;
+ protected :
+ value_compare_impl(const Pred &c) : Pred(c) {}
+ public:
+ bool operator()(const value_type& x, const value_type& y) const {
+ return Pred::operator()(x.first, y.first);
+ }
+ };
+ /// @endcond
+ typedef value_compare_impl value_compare;
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object
+ //! and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit map(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, true)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a map.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ map(const map<Key,T,Pred,Alloc>& x)
+ : m_tree(x.m_tree)
+ {}
+
+ //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ map(BOOST_INTERPROCESS_RV_REF(map) x)
+ : m_tree(boost::interprocess::move(x.m_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ map& operator=(const map<Key, T, Pred, Alloc>& x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ map& operator=(BOOST_INTERPROCESS_RV_REF(map) x)
+ { m_tree = boost::interprocess::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(m_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! Effects: If there is no key equivalent to x in the map, inserts
+ //! value_type(x, T()) into the map.
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T& operator[](const key_type& k)
+ {
+ //we can optimize this
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first)){
+ containers_detail::value_init<T> v;
+ value_type val(k, boost::interprocess::move(v.m_t));
+ i = insert(i, boost::interprocess::move(val));
+ }
+ return (*i).second;
+ }
+
+ //! Effects: If there is no key equivalent to x in the map, inserts
+ //! value_type(boost::interprocess::move(x), T()) into the map (the key is move-constructed)
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T& operator[](BOOST_INTERPROCESS_RV_REF(key_type) mk)
+ {
+ key_type &k = mk;
+ //we can optimize this
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first)){
+ value_type val(boost::interprocess::move(k), boost::interprocess::move(T()));
+ i = insert(i, boost::interprocess::move(val));
+ }
+ return (*i).second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ T& at(const key_type& k)
+ {
+ iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ const T& at(const key_type& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(map& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(const value_type& x)
+ { return m_tree.insert_unique(x); }
+
+ //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
+ //! there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(const nonconst_value_type& x)
+ { return m_tree.insert_unique(x); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_unique(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_unique(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_tree.insert_unique(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, const value_type& x)
+ { return m_tree.insert_unique(position, x); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_INTERPROCESS_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_unique(position, boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_unique(position, boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(iterator position, const nonconst_value_type& x)
+ { return m_tree.insert_unique(position, x); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(iterator position, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_tree.insert_unique(position, boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with an equivalent key.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_unique(boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with an equivalent key.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_unique(hint, boost::interprocess::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator position)
+ { return m_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const map<K1, T1, C1, A1>&,
+ const map<K1, T1, C1, A1>&);
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const map<K1, T1, C1, A1>&,
+ const map<K1, T1, C1, A1>&);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y)
+ { return x.m_tree == y.m_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y)
+ { return x.m_tree < y.m_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator!=(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y)
+ { return !(x == y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y)
+ { return y < x; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<=(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y)
+ { return !(y < x); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>=(const map<Key,T,Pred,Alloc>& x,
+ const map<Key,T,Pred,Alloc>& y)
+ { return !(x < y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline void swap(map<Key,T,Pred,Alloc>& x, map<Key,T,Pred,Alloc>& y)
+ { x.swap(y); }
+
+/// @cond
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y);
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y);
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::map<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+/// @endcond
+
+//! A multimap is a kind of associative container that supports equivalent keys
+//! (possibly containing multiple copies of the same key value) and provides for
+//! fast retrieval of values of another type T based on the keys. The multimap class
+//! supports bidirectional iterators.
+//!
+//! A multimap satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! Alloc is the allocator to allocate the value_types
+//!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
+template <class Key, class T, class Pred, class Alloc>
+class multimap
+{
+ /// @cond
+ private:
+ typedef containers_detail::rbtree<Key,
+ std::pair<const Key, T>,
+ containers_detail::select1st< std::pair<const Key, T> >,
+ Pred,
+ Alloc> tree_t;
+ tree_t m_tree; // red-black tree representing map
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(multimap)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef T mapped_type;
+ typedef Pred key_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+ typedef std::pair<key_type, mapped_type> nonconst_value_type;
+ typedef containers_detail::pair
+ <key_type, mapped_type> nonconst_impl_value_type;
+
+ /// @cond
+ class value_compare_impl
+ : public Pred,
+ public std::binary_function<value_type, value_type, bool>
+ {
+ friend class multimap<Key,T,Pred,Alloc>;
+ protected :
+ value_compare_impl(const Pred &c) : Pred(c) {}
+ public:
+ bool operator()(const value_type& x, const value_type& y) const {
+ return Pred::operator()(x.first, y.first);
+ }
+ };
+ /// @endcond
+ typedef value_compare_impl value_compare;
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
+ //! object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit multimap(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ multimap(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, false)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a multimap.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multimap(const multimap<Key,T,Pred,Alloc>& x)
+ : m_tree(x.m_tree)
+ {}
+
+ //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multimap(BOOST_INTERPROCESS_RV_REF(multimap) x)
+ : m_tree(boost::interprocess::move(x.m_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multimap& operator=(const multimap<Key,T,Pred,Alloc>& x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ multimap& operator=(BOOST_INTERPROCESS_RV_REF(multimap) x)
+ { m_tree = boost::interprocess::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(m_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(multimap& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const value_type& x)
+ { return m_tree.insert_equal(x); }
+
+ //! <b>Effects</b>: Inserts a new value constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const nonconst_value_type& x)
+ { return m_tree.insert_equal(x); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(BOOST_INTERPROCESS_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_equal(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_equal(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, const value_type& x)
+ { return m_tree.insert_equal(position, x); }
+
+ //! <b>Effects</b>: Inserts a new value constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, const nonconst_value_type& x)
+ { return m_tree.insert_equal(position, x); }
+
+ //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_INTERPROCESS_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_equal(position, boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_INTERPROCESS_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_equal(position, boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) .
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_equal(boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_equal(hint, boost::interprocess::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator position)
+ { return m_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ {return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const multimap<K1, T1, C1, A1>& x,
+ const multimap<K1, T1, C1, A1>& y);
+
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const multimap<K1, T1, C1, A1>& x,
+ const multimap<K1, T1, C1, A1>& y);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator==(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y)
+{ return x.m_tree == y.m_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y)
+{ return x.m_tree < y.m_tree; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator!=(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y)
+{ return !(x == y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y)
+{ return y < x; }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator<=(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y)
+{ return !(y < x); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline bool operator>=(const multimap<Key,T,Pred,Alloc>& x,
+ const multimap<Key,T,Pred,Alloc>& y)
+{ return !(x < y); }
+
+template <class Key, class T, class Pred, class Alloc>
+inline void swap(multimap<Key,T,Pred,Alloc>& x, multimap<Key,T,Pred,Alloc>& y)
+{ x.swap(y); }
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::multimap<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+/// @endcond
+
+}}
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_MAP_HPP */
+
Added: trunk/boost/interprocess/containers/container/set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/set.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1112 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_set/stl_multiset files. Modified by Ion Gaztanaga 2004.
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_CONTAINERS_SET_HPP
+#define BOOST_CONTAINERS_SET_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+
+#include <utility>
+#include <functional>
+#include <memory>
+
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/tree.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+// Forward declarations of operators < and ==, needed for friend declaration.
+template <class T, class Pred, class Alloc>
+inline bool operator==(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y);
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y);
+/// @endcond
+
+//! A set is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of the keys themselves.
+//! Class set supports bidirectional iterators.
+//!
+//! A set satisfies all of the requirements of a container and of a reversible container
+//! , and of an associative container. A set also provides most operations described in
+//! for unique keys.
+template <class T, class Pred, class Alloc>
+class set
+{
+ /// @cond
+ private:
+ typedef containers_detail::rbtree<T, T,
+ containers_detail::identity<T>, Pred, Alloc> tree_t;
+ tree_t m_tree; // red-black tree representing set
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(set)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef Pred key_compare;
+ typedef Pred value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object
+ //! and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit set(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, true)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a set.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ set(const set& x)
+ : m_tree(x.m_tree)
+ {}
+
+ //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ set(BOOST_INTERPROCESS_RV_REF(set) x)
+ : m_tree(boost::interprocess::move(x.m_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ set<T,Pred,Alloc>& operator=(const set<T, Pred, Alloc>& x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ set& operator=(BOOST_INTERPROCESS_RV_REF(set) x)
+ { m_tree = boost::interprocess::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(set& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(const value_type& x)
+ { return m_tree.insert_unique(x); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_tree.insert_unique(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(const_iterator p, const value_type& x)
+ { return m_tree.insert_unique(p, x); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const_iterator p, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_tree.insert_unique(p, boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is
+ //! no element in the container with equivalent value.
+ //! and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_unique(boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is
+ //! no element in the container with equivalent value.
+ //! p is a hint pointing to where the insert
+ //! should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_unique(hint, boost::interprocess::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by p.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator p)
+ { return m_tree.erase(p); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
+
+ template <class K1, class C1, class A1>
+ friend bool operator< (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
+ /// @endcond
+};
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y)
+{ return x.m_tree == y.m_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y)
+{ return x.m_tree < y.m_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator!=(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y)
+{ return !(x == y); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y)
+{ return y < x; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<=(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y)
+{ return !(y < x); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>=(const set<T,Pred,Alloc>& x,
+ const set<T,Pred,Alloc>& y)
+{ return !(x < y); }
+
+template <class T, class Pred, class Alloc>
+inline void swap(set<T,Pred,Alloc>& x, set<T,Pred,Alloc>& y)
+{ x.swap(y); }
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::set<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y);
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y);
+/// @endcond
+
+//! A multiset is a kind of associative container that supports equivalent keys
+//! (possibly contains multiple copies of the same key value) and provides for
+//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
+//!
+//! A multiset satisfies all of the requirements of a container and of a reversible
+//! container, and of an associative container). multiset also provides most operations
+//! described for duplicate keys.
+template <class T, class Pred, class Alloc>
+class multiset
+{
+ /// @cond
+ private:
+ typedef containers_detail::rbtree<T, T,
+ containers_detail::identity<T>, Pred, Alloc> tree_t;
+ tree_t m_tree; // red-black tree representing multiset
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(multiset)
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef Pred key_compare;
+ typedef Pred value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison
+ //! object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit multiset(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ multiset(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, false)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a multiset.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multiset(const multiset& x)
+ : m_tree(x.m_tree)
+ {}
+
+ //! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multiset(BOOST_INTERPROCESS_RV_REF(multiset) x)
+ : m_tree(boost::interprocess::move(x.m_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multiset<T,Pred,Alloc>& operator=(const multiset& x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ multiset& operator=(BOOST_INTERPROCESS_RV_REF(multiset) x)
+ { m_tree = boost::interprocess::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(multiset& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const value_type& x)
+ { return m_tree.insert_equal(x); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_tree.insert_equal(boost::interprocess::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(const_iterator p, const value_type& x)
+ { return m_tree.insert_equal(p, x); }
+
+ //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(const_iterator p, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return m_tree.insert_equal(p, boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: i, j are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [i,j) .
+ //!
+ //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_equal(boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)...
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_equal(hint, boost::interprocess::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by p.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator p)
+ { return m_tree.erase(p); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const multiset<K1,C1,A1>&,
+ const multiset<K1,C1,A1>&);
+ template <class K1, class C1, class A1>
+ friend bool operator< (const multiset<K1,C1,A1>&,
+ const multiset<K1,C1,A1>&);
+ /// @endcond
+};
+
+template <class T, class Pred, class Alloc>
+inline bool operator==(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y)
+{ return x.m_tree == y.m_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y)
+{ return x.m_tree < y.m_tree; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator!=(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y)
+{ return !(x == y); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y)
+{ return y < x; }
+
+template <class T, class Pred, class Alloc>
+inline bool operator<=(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y)
+{ return !(y < x); }
+
+template <class T, class Pred, class Alloc>
+inline bool operator>=(const multiset<T,Pred,Alloc>& x,
+ const multiset<T,Pred,Alloc>& y)
+{ return !(x < y); }
+
+template <class T, class Pred, class Alloc>
+inline void swap(multiset<T,Pred,Alloc>& x, multiset<T,Pred,Alloc>& y)
+{ x.swap(y); }
+
+/// @cond
+
+} //namespace interprocess_container {
+
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::multiset<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+/// @endcond
+
+}}
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_SET_HPP */
+
Added: trunk/boost/interprocess/containers/container/slist.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/slist.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1524 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2008
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef BOOST_CONTAINERS_SLIST_HPP
+#define BOOST_CONTAINERS_SLIST_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/interprocess/containers/container/detail/node_alloc_holder.hpp>
+#include <boost/intrusive/slist.hpp>
+
+
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+//Preprocessor library to emulate perfect forwarding
+#include <boost/interprocess/containers/container/detail/preprocessor.hpp>
+#endif
+
+#include <iterator>
+#include <utility>
+#include <memory>
+#include <functional>
+#include <algorithm>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+
+namespace containers_detail {
+
+template<class VoidPointer>
+struct slist_hook
+{
+ typedef typename containers_detail::bi::make_slist_base_hook
+ <containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
+};
+
+template <class T, class VoidPointer>
+struct slist_node
+ : public slist_hook<VoidPointer>::type
+{
+ #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ slist_node()
+ : m_data()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ slist_node(Args &&...args)
+ : m_data(boost::interprocess::forward<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ T m_data;
+};
+
+template<class A>
+struct intrusive_slist_type
+{
+ typedef typename A::value_type value_type;
+ typedef typename boost::pointer_to_other
+ <typename A::pointer, void>::type void_pointer;
+ typedef typename containers_detail::slist_node
+ <value_type, void_pointer> node_type;
+
+ typedef typename containers_detail::bi::make_slist
+ <node_type
+ ,containers_detail::bi::base_hook<typename slist_hook<void_pointer>::type>
+ ,containers_detail::bi::constant_time_size<true>
+ ,containers_detail::bi::size_type<typename A::size_type>
+ >::type container_type;
+ typedef container_type type ;
+};
+
+} //namespace containers_detail {
+
+/// @endcond
+
+//! An slist is a singly linked list: a list where each element is linked to the next
+//! element, but not to the previous element. That is, it is a Sequence that
+//! supports forward but not backward traversal, and (amortized) constant time
+//! insertion and removal of elements. Slists, like lists, have the important
+//! property that insertion and splicing do not invalidate iterators to list elements,
+//! and that even removal invalidates only the iterators that point to the elements
+//! that are removed. The ordering of iterators may be changed (that is,
+//! slist<T>::iterator might have a different predecessor or successor after a list
+//! operation than it did before), but the iterators themselves will not be invalidated
+//! or made to point to different elements unless that invalidation or mutation is explicit.
+//!
+//! The main difference between slist and list is that list's iterators are bidirectional
+//! iterators, while slist's iterators are forward iterators. This means that slist is
+//! less versatile than list; frequently, however, bidirectional iterators are
+//! unnecessary. You should usually use slist unless you actually need the extra
+//! functionality of list, because singly linked lists are smaller and faster than double
+//! linked lists.
+//!
+//! Important performance note: like every other Sequence, slist defines the member
+//! functions insert and erase. Using these member functions carelessly, however, can
+//! result in disastrously slow programs. The problem is that insert's first argument is
+//! an iterator p, and that it inserts the new element(s) before p. This means that
+//! insert must find the iterator just before p; this is a constant-time operation
+//! for list, since list has bidirectional iterators, but for slist it must find that
+//! iterator by traversing the list from the beginning up to p. In other words:
+//! insert and erase are slow operations anywhere but near the beginning of the slist.
+//!
+//! Slist provides the member functions insert_after and erase_after, which are constant
+//! time operations: you should always use insert_after and erase_after whenever
+//! possible. If you find that insert_after and erase_after aren't adequate for your
+//! needs, and that you often need to use insert and erase in the middle of the list,
+//! then you should probably use list instead of slist.
+template <class T, class A>
+class slist
+ : protected containers_detail::node_alloc_holder
+ <A, typename containers_detail::intrusive_slist_type<A>::type>
+{
+ /// @cond
+ typedef typename
+ containers_detail::intrusive_slist_type<A>::type Icont;
+ typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef slist <T, A> ThisType;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::allocator_v1 allocator_v1;
+ typedef typename AllocHolder::allocator_v2 allocator_v2;
+ typedef typename AllocHolder::alloc_version alloc_version;
+
+ class equal_to_value
+ {
+ typedef typename AllocHolder::value_type value_type;
+ const value_type &t_;
+
+ public:
+ equal_to_value(const value_type &t)
+ : t_(t)
+ {}
+
+ bool operator()(const value_type &t)const
+ { return t_ == t; }
+ };
+
+ template<class Pred>
+ struct ValueCompareToNodeCompare
+ : Pred
+ {
+ ValueCompareToNodeCompare(Pred pred)
+ : Pred(pred)
+ {}
+
+ bool operator()(const Node &a, const Node &b) const
+ { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
+
+ bool operator()(const Node &a) const
+ { return static_cast<const Pred&>(*this)(a.m_data); }
+ };
+ /// @endcond
+ public:
+ //! The type of object, T, stored in the list
+ typedef T value_type;
+ //! Pointer to T
+ typedef typename A::pointer pointer;
+ //! Const pointer to T
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to T
+ typedef typename A::reference reference;
+ //! Const reference to T
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! The allocator type
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef NodeAlloc stored_allocator_type;
+
+ /// @cond
+ private:
+ typedef difference_type list_difference_type;
+ typedef pointer list_pointer;
+ typedef const_pointer list_const_pointer;
+ typedef reference list_reference;
+ typedef const_reference list_const_reference;
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(slist)
+
+ //! Const iterator used to iterate through a list.
+ class const_iterator
+ /// @cond
+ : public std::iterator<std::forward_iterator_tag,
+ value_type, list_difference_type,
+ list_const_pointer, list_const_reference>
+ {
+
+ protected:
+ typename Icont::iterator m_it;
+ explicit const_iterator(typename Icont::iterator it) : m_it(it){}
+ void prot_incr(){ ++m_it; }
+
+ private:
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class slist<T, A>;
+ typedef list_difference_type difference_type;
+
+ //Constructors
+ const_iterator()
+ : m_it()
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return m_it->m_data; }
+
+ const_pointer operator->() const
+ { return const_pointer(&m_it->m_data); }
+
+ //Increment / Decrement
+ const_iterator& operator++()
+ { prot_incr(); return *this; }
+
+ const_iterator operator++(int)
+ { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
+
+ //Comparison operators
+ bool operator== (const const_iterator& r) const
+ { return m_it == r.m_it; }
+
+ bool operator!= (const const_iterator& r) const
+ { return m_it != r.m_it; }
+ }
+ /// @endcond
+ ;
+
+ //! Iterator used to iterate through a list
+ class iterator
+ /// @cond
+ : public const_iterator
+ {
+
+ private:
+ explicit iterator(typename Icont::iterator it)
+ : const_iterator(it)
+ {}
+
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class slist<T, A>;
+ typedef list_pointer pointer;
+ typedef list_reference reference;
+
+ //Constructors
+ iterator(){}
+
+ //Pointer like operators
+ reference operator*() const { return this->m_it->m_data; }
+ pointer operator->() const { return pointer(&this->m_it->m_data); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->prot_incr(); return *this; }
+
+ iterator operator++(int)
+ { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
+ }
+ /// @endcond
+ ;
+
+ public:
+ //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit slist(const allocator_type& a = allocator_type())
+ : AllocHolder(a)
+ {}
+
+ explicit slist(size_type n)
+ : AllocHolder(allocator_type())
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
+ : AllocHolder(a)
+ { this->priv_create_and_insert_nodes(this->before_begin(), n, x); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the list.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InpIt>
+ slist(InpIt first, InpIt last,
+ const allocator_type& a = allocator_type())
+ : AllocHolder(a)
+ { this->insert_after(this->before_begin(), first, last); }
+
+ //! <b>Effects</b>: Copy constructs a list.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ slist(const slist& x)
+ : AllocHolder(x)
+ { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ slist(BOOST_INTERPROCESS_RV_REF(slist) x)
+ : AllocHolder(boost::interprocess::move((AllocHolder&)x))
+ {}
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ slist& operator= (const slist& x)
+ {
+ if (&x != this){
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ slist& operator= (BOOST_INTERPROCESS_RV_REF(slist) mx)
+ {
+ if (&mx != this){
+ this->clear();
+ this->swap(mx);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~slist()
+ {} //AllocHolder clears the slist
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ public:
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
+
+ //! <b>Effects</b>: Assigns the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InpIt>
+ void assign(InpIt first, InpIt last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return iterator(this->icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return iterator(this->icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->cend(); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
+ //! when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator before_begin()
+ { return iterator(end()); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+ //! that, when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator before_begin() const
+ { return this->cbefore_begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+ //! that, when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbefore_begin() const
+ { return const_iterator(end()); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->icont().size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return AllocHolder::max_size(); }
+
+ //! <b>Effects</b>: Returns true if the list contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements on *this and x.
+ void swap(slist& x)
+ { AllocHolder::swap(x); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return *this->begin(); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->begin(); }
+
+ //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(const value_type& x)
+ { this->icont().push_front(*this->create_node(x)); }
+
+ //! <b>Effects</b>: Constructs a new element in the beginning of the list
+ //! and moves the resources of t to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(BOOST_INTERPROCESS_RV_REF(T) x)
+ { this->icont().push_front(*this->create_node(boost::interprocess::move(x))); }
+
+ //! <b>Effects</b>: Removes the first element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void pop_front()
+ { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
+
+ //! <b>Returns</b>: The iterator to the element before i in the sequence.
+ //! Returns the end-iterator, if either i is the begin-iterator or the
+ //! sequence is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ iterator previous(iterator p)
+ { return iterator(this->icont().previous(p.get())); }
+
+ //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
+ //! Returns the end-const_iterator, if either i is the begin-const_iterator or
+ //! the sequence is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ const_iterator previous(const_iterator p)
+ { return const_iterator(this->icont().previous(p.get())); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts a copy of the value after the p pointed
+ //! by prev_p.
+ //!
+ //! <b>Returns</b>: An iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ iterator insert_after(const_iterator prev_pos, const value_type& x)
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts a move constructed copy object from the value after the
+ //! p pointed by prev_pos.
+ //!
+ //! <b>Returns</b>: An iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ iterator insert_after(const_iterator prev_pos, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(boost::interprocess::move(x)))); }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x after prev_pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
+ { this->priv_create_and_insert_nodes(prev_pos, n, x); }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts the range pointed by [first, last)
+ //! after the p prev_pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements inserted.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ template <class InIter>
+ void insert_after(const_iterator prev_pos, InIter first, InIter last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InIter, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p.
+ iterator insert(const_iterator p, const value_type& x)
+ { return this->insert_after(previous(p), x); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p.
+ iterator insert(const_iterator p, BOOST_INTERPROCESS_RV_REF(value_type) x)
+ { return this->insert_after(previous(p), boost::interprocess::move(x)); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
+ void insert(const_iterator p, size_type n, const value_type& x)
+ { return this->insert_after(previous(p), n, x); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last) plus
+ //! linear to the elements before p.
+ template <class InIter>
+ void insert(const_iterator p, InIter first, InIter last)
+ { return this->insert_after(previous(p), first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the front of the list
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ { this->emplace_after(this->cbefore_begin(), boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ { return this->emplace_after(this->previous(p), boost::interprocess::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... after prev
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace_after(const_iterator prev, Args&&... args)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node(boost::interprocess::forward<Args>(args)...);
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert_after(prev.get(), *node));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_front()
+ { this->emplace_after(this->cbefore_begin()); }
+
+ iterator emplace(const_iterator p)
+ { return this->emplace_after(this->previous(p)); }
+
+ iterator emplace_after(const_iterator prev)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node();
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert_after(prev.get(), *node));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace \
+ (this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace \
+ (const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_after \
+ (this->previous(p), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_after \
+ (const_iterator prev, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
+ new ((void*)containers_detail::get_pointer(d.get())) \
+ Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ NodePtr node = d.get(); \
+ d.release(); \
+ return iterator(this->icont().insert_after(prev.get(), *node)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element after the element pointed by prev_pos
+ //! of the list.
+ //!
+ //! <b>Returns</b>: the first element remaining beyond the removed elements,
+ //! or end() if no such element exists.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
+ iterator erase_after(const_iterator prev_pos)
+ {
+ return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
+ }
+
+ //! <b>Effects</b>: Erases the range (before_first, last) from
+ //! the list.
+ //!
+ //! <b>Returns</b>: the first element remaining beyond the removed elements,
+ //! or end() if no such element exists.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of erased elements.
+ //!
+ //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
+ iterator erase_after(const_iterator before_first, const_iterator last)
+ {
+ return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Erases the element at p p.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before p.
+ iterator erase(const_iterator p)
+ { return iterator(this->erase_after(previous(p))); }
+
+ //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+ //!
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last plus
+ //! linear to the elements before first.
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(this->erase_after(previous(first), last)); }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+ while (++(cur_next = cur) != end_n && new_size > 0){
+ --new_size;
+ cur = cur_next;
+ }
+ if (cur_next != end_n)
+ this->erase_after(const_iterator(cur), const_iterator(end_n));
+ else
+ this->insert_after(const_iterator(cur), new_size, x);
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+ size_type len = this->size();
+ size_type left = new_size;
+
+ while (++(cur_next = cur) != end_n && left > 0){
+ --left;
+ cur = cur_next;
+ }
+ if (cur_next != end_n){
+ this->erase_after(const_iterator(cur), const_iterator(end_n));
+ }
+ else{
+ this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
+ }
+ }
+
+ //! <b>Effects</b>: Erases all the elements of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the list.
+ void clear()
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the elements in x.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after(prev_pos.get(), x.icont());
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! after the element pointed by prev_pos.
+ //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
+ //!
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the number of transferred elements.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
+ //! n == std::distance(before_first, before_last)
+ //!
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last,
+ size_type n)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType& x)
+ { this->splice_after(this->previous(p), x); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x, const_iterator i)
+ { this->splice_after(previous(p), x, i); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
+ //! and in distance(first, last).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+ { this->splice_after(previous(p), x, previous(first), previous(last)); }
+
+ //! <b>Effects</b>: Reverses the order of elements in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time.
+ //!
+ //! <b>Note</b>: Iterators and references are not invalidated
+ void reverse()
+ { this->icont().reverse(); }
+
+ //! <b>Effects</b>: Removes all the elements that compare equal to value.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void remove(const T& value)
+ { remove_if(equal_to_value(value)); }
+
+ //! <b>Effects</b>: Removes all the elements for which a specified
+ //! predicate is satisfied.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class Pred>
+ void remove_if(Pred pred)
+ {
+ typedef ValueCompareToNodeCompare<Pred> Predicate;
+ this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that are equal from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void unique()
+ { this->unique(value_equal()); }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that satisfy some binary predicate from the list.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class Pred>
+ void unique(Pred pred)
+ {
+ typedef ValueCompareToNodeCompare<Pred> Predicate;
+ this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Requires</b>: The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this according to std::less<value_type>. The merge is stable;
+ //! that is, if an element from *this is equivalent to one from x, then the element
+ //! from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ void merge(slist & x)
+ { this->merge(x, value_less()); }
+
+ //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+ //! ordering and both *this and x must be sorted according to that ordering
+ //! The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this. The merge is stable; that is, if an element from *this is
+ //! equivalent to one from x, then the element from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ //!
+ //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ template <class StrictWeakOrdering>
+ void merge(slist& x, StrictWeakOrdering comp)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+ else{
+ throw std::runtime_error("list::merge called with unequal allocators");
+ }
+ }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ void sort()
+ { this->sort(value_less()); }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ template <class StrictWeakOrdering>
+ void sort(StrictWeakOrdering comp)
+ {
+ // nothing if the slist has length 0 or 1.
+ if (this->size() < 2)
+ return;
+ this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+
+ /// @cond
+ private:
+
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, InpIterator beg, InpIterator end)
+ {
+ typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat());
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+ {
+ for (; beg != end; ++beg){
+ this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
+ ++prev;
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+ typename Icont::const_iterator prev_;
+
+ public:
+ insertion_functor(Icont &icont, typename Icont::const_iterator prev)
+ : icont_(icont), prev_(prev)
+ {}
+
+ void operator()(Node &n)
+ { prev_ = this->icont_.insert_after(prev_, n); }
+ };
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
+ }
+
+ //Default constructed version
+ void priv_create_and_insert_nodes(const_iterator prev, size_type n)
+ {
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator());
+ }
+
+ //Copy constructed version
+ void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator());
+ }
+
+ //Dispatch to detect iterator range or integer overloads
+ template <class InputIter>
+ void priv_insert_dispatch(const_iterator prev,
+ InputIter first, InputIter last,
+ containers_detail::false_)
+ { this->priv_create_and_insert_nodes(prev, first, last); }
+
+ template<class Integer>
+ void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, containers_detail::true_)
+ { this->priv_create_and_insert_nodes(prev, n, x); }
+
+ void priv_fill_assign(size_type n, const T& val)
+ {
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
+ for ( ; node != end_n && n > 0 ; --n){
+ *node = val;
+ prev = node;
+ ++node;
+ }
+ if (n > 0)
+ this->priv_create_and_insert_nodes(prev, n, val);
+ else
+ this->erase_after(prev, end_n);
+ }
+
+ template <class Int>
+ void priv_assign_dispatch(Int n, Int val, containers_detail::true_)
+ { this->priv_fill_assign((size_type) n, (T)val); }
+
+ template <class InpIt>
+ void priv_assign_dispatch(InpIt first, InpIt last, containers_detail::false_)
+ {
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
+ while (node != end_n && first != last){
+ *node = *first;
+ prev = node;
+ ++node;
+ ++first;
+ }
+ if (first != last)
+ this->priv_create_and_insert_nodes(prev, first, last);
+ else
+ this->erase_after(prev, end_n);
+ }
+
+ template <class Int>
+ void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, containers_detail::true_)
+ { this->priv_create_and_insert_nodes(prev_pos, n, x); }
+
+ template <class InIter>
+ void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, containers_detail::false_)
+ { this->priv_create_and_insert_nodes(prev_pos, first, last); }
+
+ //Functors for member algorithm defaults
+ struct value_less
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a < b; }
+ };
+
+ struct value_equal
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a == b; }
+ };
+
+ struct value_equal_to_this
+ {
+ explicit value_equal_to_this(const value_type &ref)
+ : m_ref(ref){}
+
+ bool operator()(const value_type &val) const
+ { return m_ref == val; }
+
+ const value_type &m_ref;
+ };
+ /// @endcond
+};
+
+template <class T, class A>
+inline bool
+operator==(const slist<T,A>& x, const slist<T,A>& y)
+{
+ if(x.size() != y.size()){
+ return false;
+ }
+ typedef typename slist<T,A>::const_iterator const_iterator;
+ const_iterator end1 = x.end();
+
+ const_iterator i1 = x.begin();
+ const_iterator i2 = y.begin();
+ while (i1 != end1 && *i1 == *i2){
+ ++i1;
+ ++i2;
+ }
+ return i1 == end1;
+}
+
+template <class T, class A>
+inline bool
+operator<(const slist<T,A>& sL1, const slist<T,A>& sL2)
+{
+ return std::lexicographical_compare
+ (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
+}
+
+template <class T, class A>
+inline bool
+operator!=(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return !(sL1 == sL2); }
+
+template <class T, class A>
+inline bool
+operator>(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return sL2 < sL1; }
+
+template <class T, class A>
+inline bool
+operator<=(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return !(sL2 < sL1); }
+
+template <class T, class A>
+inline bool
+operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return !(sL1 < sL2); }
+
+template <class T, class A>
+inline void swap(slist<T,A>& x, slist<T,A>& y)
+ { x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::slist<T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+
+} //namespace interprocess {
+
+namespace interprocess_container {
+
+/// @endcond
+
+}} //namespace boost{ namespace interprocess_container {
+
+// Specialization of insert_iterator so that insertions will be constant
+// time rather than linear time.
+
+///@cond
+
+//Ummm, I don't like to define things in namespace std, but
+//there is no other way
+namespace std {
+
+template <class T, class A>
+class insert_iterator<boost::interprocess_container::slist<T, A> >
+{
+ protected:
+ typedef boost::interprocess_container::slist<T, A> Container;
+ Container* container;
+ typename Container::iterator iter;
+ public:
+ typedef Container container_type;
+ typedef output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef void difference_type;
+ typedef void pointer;
+ typedef void reference;
+
+ insert_iterator(Container& x,
+ typename Container::iterator i,
+ bool is_previous = false)
+ : container(&x), iter(is_previous ? i : x.previous(i)){ }
+
+ insert_iterator<Container>&
+ operator=(const typename Container::value_type& value)
+ {
+ iter = container->insert_after(iter, value);
+ return *this;
+ }
+ insert_iterator<Container>& operator*(){ return *this; }
+ insert_iterator<Container>& operator++(){ return *this; }
+ insert_iterator<Container>& operator++(int){ return *this; }
+};
+
+} //namespace std;
+
+///@endcond
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_SLIST_HPP */
Added: trunk/boost/interprocess/containers/container/stable_vector.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/stable_vector.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1351 @@
+/* Stable vector.
+ *
+ * Copyright 2008 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef STABLE_VECTOR_HPP_3A7EB5C0_55BF_11DD_AE16_0800200C9A66
+#define STABLE_VECTOR_HPP_3A7EB5C0_55BF_11DD_AE16_0800200C9A66
+
+#include <algorithm>
+#include <stdexcept>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/get_pointer.hpp>
+
+#define STABLE_VECTOR_USE_CONTAINERS_VECTOR
+
+#if defined (STABLE_VECTOR_USE_CONTAINERS_VECTOR)
+#include <boost/interprocess/containers/container/vector.hpp>
+#else
+#include <vector>
+#endif //STABLE_VECTOR_USE_CONTAINERS_VECTOR
+
+//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+
+#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+#include <boost/assert.hpp>
+#endif
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+
+namespace stable_vector_detail{
+
+template<class SmartPtr>
+struct smart_ptr_type
+{
+ typedef typename SmartPtr::value_type value_type;
+ typedef value_type *pointer;
+ static pointer get (const SmartPtr &smartptr)
+ { return smartptr.get();}
+};
+
+template<class T>
+struct smart_ptr_type<T*>
+{
+ typedef T value_type;
+ typedef value_type *pointer;
+ static pointer get (pointer ptr)
+ { return ptr;}
+};
+
+template<class Ptr>
+inline typename smart_ptr_type<Ptr>::pointer get_pointer(const Ptr &ptr)
+{ return smart_ptr_type<Ptr>::get(ptr); }
+
+template <class C>
+class clear_on_destroy
+{
+ public:
+ clear_on_destroy(C &c)
+ : c_(c), do_clear_(true)
+ {}
+
+ void release()
+ { do_clear_ = false; }
+
+ ~clear_on_destroy()
+ {
+ if(do_clear_){
+ c_.clear();
+ c_.clear_pool();
+ }
+ }
+
+ private:
+ C &c_;
+ bool do_clear_;
+};
+
+template <class T, class Difference = std::ptrdiff_t>
+class constant_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+ typedef constant_iterator<T, Difference> this_type;
+
+ public:
+ explicit constant_iterator(const T &ref, Difference range_size)
+ : m_ptr(&ref), m_num(range_size){}
+
+ //Constructors
+ constant_iterator()
+ : m_ptr(0), m_num(0){}
+
+ constant_iterator& operator++()
+ { increment(); return *this; }
+
+ constant_iterator operator++(int)
+ {
+ constant_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ constant_iterator& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ constant_iterator operator+(Difference off) const
+ {
+ constant_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend constant_iterator operator+(Difference off, const constant_iterator& right)
+ { return right + off; }
+
+ constant_iterator& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ constant_iterator operator-(Difference off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ private:
+ const T * m_ptr;
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ { return *m_ptr; }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template<class VoidPtr>
+struct node_type_base
+{/*
+ node_type_base(VoidPtr p)
+ : up(p)
+ {}*/
+ node_type_base()
+ {}
+ void set_pointer(VoidPtr p)
+ { up = p; }
+
+ VoidPtr up;
+};
+
+template<typename VoidPointer, typename T>
+struct node_type
+ : public node_type_base<VoidPointer>
+{
+ #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ node_type()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ node_type(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : value(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ node_type(Args &&...args)
+ : value(boost::interprocess::forward<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ void set_pointer(VoidPointer p)
+ { node_type_base<VoidPointer>::set_pointer(p); }
+
+ T value;
+};
+
+template<typename T, typename Value, typename Pointer>
+class iterator
+ : public std::iterator< std::random_access_iterator_tag
+ , const typename std::iterator_traits<Pointer>::value_type
+ , typename std::iterator_traits<Pointer>::difference_type
+ , Pointer
+ , Value &>
+{
+
+ typedef typename boost::pointer_to_other
+ <Pointer, void>::type void_ptr;
+ typedef node_type<void_ptr, T> node_type_t;
+ typedef typename boost::pointer_to_other
+ <void_ptr, node_type_t>::type node_type_ptr_t;
+ typedef typename boost::pointer_to_other
+ <void_ptr, void_ptr>::type void_ptr_ptr;
+
+ friend class iterator<T, const T, typename boost::pointer_to_other<Pointer, T>::type>;
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef Value value_type;
+ typedef typename std::iterator_traits
+ <Pointer>::difference_type difference_type;
+ typedef Pointer pointer;
+ typedef Value & reference;
+
+ iterator()
+ {}
+
+ explicit iterator(node_type_ptr_t pn)
+ : pn(pn)
+ {}
+
+ iterator(const iterator<T, T, typename boost::pointer_to_other<Pointer, T>::type >& x)
+ : pn(x.pn)
+ {}
+
+ private:
+ static node_type_ptr_t node_ptr_cast(void_ptr p)
+ {
+ using boost::get_pointer;
+ return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static void_ptr_ptr void_ptr_ptr_cast(void_ptr p)
+ {
+ using boost::get_pointer;
+ return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ Value& dereference() const
+ { return pn->value; }
+ bool equal(const iterator& x) const
+ { return pn==x.pn; }
+ void increment()
+ { pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+1)); }
+ void decrement()
+ { pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)-1)); }
+ void advance(std::ptrdiff_t n)
+ { pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+n)); }
+ std::ptrdiff_t distance_to(const iterator& x)const
+ { return void_ptr_ptr_cast(x.pn->up) - void_ptr_ptr_cast(pn->up); }
+
+ public:
+ //Pointer like operators
+ reference operator*() const { return this->dereference(); }
+ pointer operator->() const { return pointer(&this->dereference()); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->increment(); return *this; }
+
+ iterator operator++(int)
+ { iterator tmp(*this); ++*this; return iterator(tmp); }
+
+ iterator& operator--()
+ { this->decrement(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp(*this); --*this; return iterator(tmp); }
+
+ reference operator[](difference_type off) const
+ {
+ iterator tmp(*this);
+ tmp += off;
+ return *tmp;
+ }
+
+ iterator& operator+=(difference_type off)
+ {
+ pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+off));
+ return *this;
+ }
+
+ iterator operator+(difference_type off) const
+ {
+ iterator tmp(*this);
+ tmp += off;
+ return tmp;
+ }
+
+ friend iterator operator+(difference_type off, const iterator& right)
+ {
+ iterator tmp(right);
+ tmp += off;
+ return tmp;
+ }
+
+ iterator& operator-=(difference_type off)
+ { *this += -off; return *this; }
+
+ iterator operator-(difference_type off) const
+ {
+ iterator tmp(*this);
+ tmp -= off;
+ return tmp;
+ }
+
+ difference_type operator-(const iterator& right) const
+ {
+ void_ptr_ptr p1 = void_ptr_ptr_cast(this->pn->up);
+ void_ptr_ptr p2 = void_ptr_ptr_cast(right.pn->up);
+ return p1 - p2;
+ }
+
+ //Comparison operators
+ bool operator== (const iterator& r) const
+ { return pn == r.pn; }
+
+ bool operator!= (const iterator& r) const
+ { return pn != r.pn; }
+
+ bool operator< (const iterator& r) const
+ { return void_ptr_ptr_cast(pn->up) < void_ptr_ptr_cast(r.pn->up); }
+
+ bool operator<= (const iterator& r) const
+ { return void_ptr_ptr_cast(pn->up) <= void_ptr_ptr_cast(r.pn->up); }
+
+ bool operator> (const iterator& r) const
+ { return void_ptr_ptr_cast(pn->up) > void_ptr_ptr_cast(r.pn->up); }
+
+ bool operator>= (const iterator& r) const
+ { return void_ptr_ptr_cast(pn->up) >= void_ptr_ptr_cast(r.pn->up); }
+
+ node_type_ptr_t pn;
+};
+
+/*
+class node_access
+{
+ public:
+ template<typename T, typename Value, typename VoidPointer>
+ static typename iterator<T, Value, VoidPointer>::node_type_t* get(const iterator<T,Value,VoidPointer>& it)
+ {
+ return stable_vector_detail::get_pointer(it.pn);
+ }
+};
+*/
+
+template<class Allocator, unsigned int Version>
+struct select_multiallocation_chain
+{
+ typedef typename Allocator::multiallocation_chain type;
+};
+
+template<class Allocator>
+struct select_multiallocation_chain<Allocator, 1>
+{
+ typedef typename Allocator::template
+ rebind<void>::other::pointer void_ptr;
+ typedef containers_detail::basic_multiallocation_cached_slist<void_ptr> multialloc_cached;
+ typedef containers_detail::basic_multiallocation_cached_counted_slist
+ <multialloc_cached> multialloc_cached_counted;
+ typedef boost::interprocess_container::containers_detail::transform_multiallocation_chain
+ <multialloc_cached_counted, typename Allocator::value_type> type;
+};
+
+} //namespace stable_vector_detail
+
+#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+#define STABLE_VECTOR_CHECK_INVARIANT \
+invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
+BOOST_JOIN(check_invariant_,__LINE__).touch();
+#else
+
+#define STABLE_VECTOR_CHECK_INVARIANT
+
+#endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+/// @endcond
+
+template<typename T,typename Allocator=std::allocator<T> >
+class stable_vector
+{
+ typedef typename Allocator::template
+ rebind<void>::other::pointer void_ptr;
+ typedef typename Allocator::template
+ rebind<void_ptr>::other::pointer void_ptr_ptr;
+ typedef stable_vector_detail::node_type
+ <void_ptr, T> node_type_t;
+ typedef typename Allocator::template
+ rebind<node_type_t>::other::pointer node_type_ptr_t;
+ typedef stable_vector_detail::node_type_base
+ <void_ptr> node_type_base_t;
+ typedef typename Allocator::template
+ rebind<node_type_base_t>::other::pointer node_type_base_ptr_t;
+ typedef
+ #if defined (STABLE_VECTOR_USE_CONTAINERS_VECTOR)
+ ::boost::interprocess_container::
+ #else
+ ::std::
+ #endif //STABLE_VECTOR_USE_CONTAINERS_VECTOR
+ vector<void_ptr,
+ typename Allocator::
+ template rebind<void_ptr>::other
+ > impl_type;
+ typedef typename impl_type::iterator impl_iterator;
+ typedef typename impl_type::const_iterator const_impl_iterator;
+
+ typedef ::boost::interprocess_container::containers_detail::
+ integral_constant<unsigned, 1> allocator_v1;
+ typedef ::boost::interprocess_container::containers_detail::
+ integral_constant<unsigned, 2> allocator_v2;
+ typedef ::boost::interprocess_container::containers_detail::integral_constant
+ <unsigned, boost::interprocess_container::containers_detail::
+ version<Allocator>::value> alloc_version;
+ typedef typename Allocator::
+ template rebind<node_type_t>::other node_allocator_type;
+
+ node_type_ptr_t allocate_one()
+ { return this->allocate_one(alloc_version()); }
+
+ node_type_ptr_t allocate_one(allocator_v1)
+ { return get_al().allocate(1); }
+
+ node_type_ptr_t allocate_one(allocator_v2)
+ { return get_al().allocate_one(); }
+
+ void deallocate_one(node_type_ptr_t p)
+ { return this->deallocate_one(p, alloc_version()); }
+
+ void deallocate_one(node_type_ptr_t p, allocator_v1)
+ { get_al().deallocate(p, 1); }
+
+ void deallocate_one(node_type_ptr_t p, allocator_v2)
+ { get_al().deallocate_one(p); }
+
+ friend class stable_vector_detail::clear_on_destroy<stable_vector>;
+
+ public:
+ // types:
+
+ typedef typename Allocator::reference reference;
+ typedef typename Allocator::const_reference const_reference;
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::const_pointer const_pointer;
+ typedef stable_vector_detail::iterator
+ <T,T, pointer> iterator;
+ typedef stable_vector_detail::iterator
+ <T,const T, const_pointer> const_iterator;
+ typedef typename impl_type::size_type size_type;
+ typedef typename iterator::difference_type difference_type;
+ typedef T value_type;
+ typedef Allocator allocator_type;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ private:
+ static const size_type ExtraPointers = 3;
+ typedef typename stable_vector_detail::
+ select_multiallocation_chain
+ < node_allocator_type
+ , alloc_version::value
+ >::type multiallocation_chain;
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(stable_vector)
+
+ // construct/copy/destroy:
+ explicit stable_vector(const Allocator& al=Allocator())
+ : internal_data(al),impl(al)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ }
+
+ stable_vector(size_type n,const T& t=T(),const Allocator& al=Allocator())
+ : internal_data(al),impl(al)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), n, t);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ template <class InputIterator>
+ stable_vector(InputIterator first,InputIterator last,const Allocator& al=Allocator())
+ : internal_data(al),impl(al)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), first, last);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ stable_vector(const stable_vector& x)
+ : internal_data(x.get_al()),impl(x.get_al())
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), x.begin(), x.end());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ stable_vector(BOOST_INTERPROCESS_RV_REF(stable_vector) x)
+ : internal_data(x.get_al()),impl(x.get_al())
+ { this->swap(x); }
+
+ ~stable_vector()
+ {
+ this->clear();
+ clear_pool();
+ }
+
+ stable_vector& operator=(const stable_vector &x)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if (this != &x) {
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ stable_vector& operator=(BOOST_INTERPROCESS_RV_REF(stable_vector) x)
+ {
+ if (&x != this){
+ this->swap(x);
+ x.clear();
+ }
+ return *this;
+ }
+
+ template<typename InputIterator>
+ void assign(InputIterator first,InputIterator last)
+ {
+ assign_dispatch(first, last, boost::is_integral<InputIterator>());
+ }
+
+ void assign(size_type n,const T& t)
+ {
+ typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ return assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+ }
+
+ allocator_type get_allocator()const {return get_al();}
+
+ // iterators:
+
+ iterator begin()
+ { return (impl.empty()) ? end(): iterator(node_ptr_cast(impl.front())) ; }
+
+ const_iterator begin()const
+ { return (impl.empty()) ? cend() : const_iterator(node_ptr_cast(impl.front())) ; }
+
+ iterator end() {return iterator(get_end_node());}
+ const_iterator end()const {return const_iterator(get_end_node());}
+
+ reverse_iterator rbegin() {return reverse_iterator(this->end());}
+ const_reverse_iterator rbegin()const {return const_reverse_iterator(this->end());}
+ reverse_iterator rend() {return reverse_iterator(this->begin());}
+ const_reverse_iterator rend()const {return const_reverse_iterator(this->begin());}
+
+ const_iterator cbegin()const {return this->begin();}
+ const_iterator cend()const {return this->end();}
+ const_reverse_iterator crbegin()const{return this->rbegin();}
+ const_reverse_iterator crend()const {return this->rend();}
+
+ // capacity:
+ size_type size() const
+ { return impl.empty() ? 0 : (impl.size() - ExtraPointers); }
+
+ size_type max_size() const
+ { return impl.max_size() - ExtraPointers; }
+
+ size_type capacity() const
+ {
+ if(!impl.capacity()){
+ return 0;
+ }
+ else{
+ const size_type num_nodes = this->impl.size() + this->internal_data.pool_size;
+ const size_type num_buck = this->impl.capacity();
+ return (num_nodes < num_buck) ? num_nodes : num_buck;
+ }
+ }
+
+ bool empty() const
+ { return impl.empty() || impl.size() == ExtraPointers; }
+
+ void resize(size_type n, const T& t)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > size())
+ this->insert(this->cend(), n - this->size(), t);
+ else if(n < this->size())
+ this->erase(this->cbegin() + n, this->cend());
+ }
+
+ void resize(size_type n)
+ {
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > size())
+ this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
+ else if(n < this->size())
+ this->erase(this->cbegin() + n, this->cend());
+ }
+
+ void reserve(size_type n)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > this->max_size())
+ throw std::bad_alloc();
+
+ size_type size = this->size();
+ size_type old_capacity = this->capacity();
+ if(n > old_capacity){
+ this->initialize_end_node(n);
+ const void * old_ptr = &impl[0];
+ impl.reserve(n + ExtraPointers);
+ bool realloced = &impl[0] != old_ptr;
+ //Fix the pointers for the newly allocated buffer
+ if(realloced){
+ this->align_nodes(impl.begin(), impl.begin()+size+1);
+ }
+ //Now fill pool if data is not enough
+ if((n - size) > this->internal_data.pool_size){
+ this->add_to_pool((n - size) - this->internal_data.pool_size, alloc_version());
+ }
+ }
+ }
+
+ template<class AllocatorVersion>
+ void clear_pool(AllocatorVersion,
+ typename boost::interprocess_container::containers_detail::enable_if_c
+ <boost::interprocess_container::containers_detail::is_same<AllocatorVersion, allocator_v1>
+ ::value>::type * = 0)
+ {
+ if(!impl.empty() && impl.back()){
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+
+ multiallocation_chain holder(p1, p2, this->internal_data.pool_size);
+ while(!holder.empty()){
+ node_type_ptr_t n = holder.front();
+ holder.pop_front();
+ this->deallocate_one(n);
+ }
+ p1 = p2 = 0;
+ this->internal_data.pool_size = 0;
+ }
+ }
+
+ template<class AllocatorVersion>
+ void clear_pool(AllocatorVersion,
+ typename boost::interprocess_container::containers_detail::enable_if_c
+ <boost::interprocess_container::containers_detail::is_same<AllocatorVersion, allocator_v2>
+ ::value>::type * = 0)
+ {
+
+ if(!impl.empty() && impl.back()){
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder(p1, p2, this->internal_data.pool_size);
+ get_al().deallocate_individual(boost::interprocess::move(holder));
+ p1 = p2 = 0;
+ this->internal_data.pool_size = 0;
+ }
+ }
+
+ void clear_pool()
+ {
+ this->clear_pool(alloc_version());
+ }
+
+ template<class AllocatorVersion>
+ void add_to_pool(size_type n, AllocatorVersion,
+ typename boost::interprocess_container::containers_detail::enable_if_c
+ <boost::interprocess_container::containers_detail::is_same<AllocatorVersion, allocator_v1>
+ ::value>::type * = 0)
+ {
+ size_type remaining = n;
+ while(remaining--){
+ this->put_in_pool(this->allocate_one());
+ }
+ }
+
+ template<class AllocatorVersion>
+ void add_to_pool(size_type n, AllocatorVersion,
+ typename boost::interprocess_container::containers_detail::enable_if_c
+ <boost::interprocess_container::containers_detail::is_same<AllocatorVersion, allocator_v2>
+ ::value>::type * = 0)
+ {
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder(p1, p2, this->internal_data.pool_size);
+ BOOST_STATIC_ASSERT((boost::interprocess::is_movable<multiallocation_chain>::value == true));
+ multiallocation_chain m (get_al().allocate_individual(n));
+ holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
+ this->internal_data.pool_size += n;
+ std::pair<void_ptr, void_ptr> data(holder.extract_data());
+ p1 = data.first;
+ p2 = data.second;
+ }
+
+ void put_in_pool(node_type_ptr_t p)
+ {
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder(p1, p2, internal_data.pool_size);
+ holder.push_front(p);
+ ++this->internal_data.pool_size;
+ std::pair<void_ptr, void_ptr> ret(holder.extract_data());
+ p1 = ret.first;
+ p2 = ret.second;
+ }
+
+ node_type_ptr_t get_from_pool()
+ {
+ if(!impl.back()){
+ return node_type_ptr_t(0);
+ }
+ else{
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder(p1, p2, internal_data.pool_size);
+ node_type_ptr_t ret = holder.front();
+ holder.pop_front();
+ std::pair<void_ptr, void_ptr> data(holder.extract_data());
+ p1 = data.first;
+ p2 = data.second;
+ --this->internal_data.pool_size;
+ return ret;
+ }
+ }
+
+ // element access:
+
+ reference operator[](size_type n){return value(impl[n]);}
+ const_reference operator[](size_type n)const{return value(impl[n]);}
+
+ const_reference at(size_type n)const
+ {
+ if(n>=size())
+ throw std::out_of_range("invalid subscript at stable_vector::at");
+ return operator[](n);
+ }
+
+ reference at(size_type n)
+ {
+ if(n>=size())
+ throw std::out_of_range("invalid subscript at stable_vector::at");
+ return operator[](n);
+ }
+
+ reference front()
+ { return value(impl.front()); }
+
+ const_reference front()const
+ { return value(impl.front()); }
+
+ reference back()
+ { return value(*(&impl.back() - ExtraPointers)); }
+
+ const_reference back()const
+ { return value(*(&impl.back() - ExtraPointers)); }
+
+ // modifiers:
+
+ void push_back(const T& t)
+ { this->insert(end(), t); }
+
+ void push_back(BOOST_INTERPROCESS_RV_REF(T) t)
+ { this->insert(end(), boost::interprocess::move(t)); }
+
+ void pop_back()
+ { this->erase(this->end()-1); }
+
+ iterator insert(const_iterator position, const T& t)
+ {
+ typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
+ }
+
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(T) x)
+ {
+ typedef repeat_iterator<T, difference_type> repeat_it;
+ typedef boost::interprocess::move_iterator<repeat_it> repeat_move_it;
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position
+ ,repeat_move_it(repeat_it(x, 1))
+ ,repeat_move_it(repeat_it()));
+ return iterator(this->begin() + pos_n);
+ }
+
+ void insert(const_iterator position, size_type n, const T& t)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ this->insert_not_iter(position, n, t);
+ }
+
+ template <class InputIterator>
+ void insert(const_iterator position,InputIterator first, InputIterator last)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ this->insert_iter(position,first,last,
+ boost::mpl::not_<boost::is_integral<InputIterator> >());
+ }
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template<class ...Args>
+ void emplace_back(Args &&...args)
+ {
+ typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor> EmplaceIterator;
+ EmplaceFunctor ef(boost::interprocess::forward<Args>(args)...);
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template<class ...Args>
+ iterator emplace(const_iterator position, Args && ...args)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor> EmplaceIterator;
+ EmplaceFunctor ef(boost::interprocess::forward<Args>(args)...);
+ this->insert(position, EmplaceIterator(ef), EmplaceIterator());
+ return iterator(this->begin() + pos_n);
+ }
+
+ #else
+
+ void emplace_back()
+ {
+ typedef emplace_functor<node_type_t> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor> EmplaceIterator;
+ EmplaceFunctor ef;
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+ }
+
+ iterator emplace(const_iterator position)
+ {
+ typedef emplace_functor<node_type_t> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor> EmplaceIterator;
+ EmplaceFunctor ef;
+ size_type pos_n = position - this->cbegin();
+ this->insert(position, EmplaceIterator(ef), EmplaceIterator());
+ return iterator(this->begin() + pos_n);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ <node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
+ typedef emplace_iterator<node_type_t, EmplaceFunctor> EmplaceIterator; \
+ EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ <node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
+ typedef emplace_iterator<node_type_t, EmplaceFunctor> EmplaceIterator; \
+ EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ size_type pos_n = pos - this->cbegin(); \
+ this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
+ return iterator(this->begin() + pos_n); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator erase(const_iterator position)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ difference_type d=position-this->cbegin();
+ impl_iterator it=impl.begin()+d;
+ this->delete_node(*it);
+ impl.erase(it);
+ this->align_nodes(impl.begin()+d,get_last_align());
+ return this->begin()+d;
+ }
+
+ iterator erase(const_iterator first, const_iterator last)
+ { return priv_erase(first, last, alloc_version()); }
+
+ void swap(stable_vector & x)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ this->swap_impl(*this,x);
+ }
+
+ void clear()
+ { this->erase(this->cbegin(),this->cend()); }
+
+ /// @cond
+ private:
+
+ void insert_iter_prolog(size_type n, difference_type d)
+ {
+ initialize_end_node(n);
+ const void* old_ptr = &impl[0];
+ //size_type old_capacity = capacity();
+ //size_type old_size = size();
+ impl.insert(impl.begin()+d, n, 0);
+ bool realloced = &impl[0] != old_ptr;
+ //Fix the pointers for the newly allocated buffer
+ if(realloced){
+ align_nodes(impl.begin(), impl.begin()+d);
+ }
+ }
+
+ template<typename InputIterator>
+ void assign_dispatch(InputIterator first, InputIterator last, boost::mpl::false_)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ iterator first1 = this->begin();
+ iterator last1 = this->end();
+ for ( ; first1 != last1 && first != last; ++first1, ++first)
+ *first1 = *first;
+ if (first == last){
+ this->erase(first1, last1);
+ }
+ else{
+ this->insert(last1, first, last);
+ }
+ }
+
+ template<typename Integer>
+ void assign_dispatch(Integer n, Integer t, boost::mpl::true_)
+ {
+ typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+ }
+
+ iterator priv_erase(const_iterator first, const_iterator last, allocator_v1)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
+ if(d1 != d2){
+ impl_iterator it1(impl.begin() + d1), it2(impl.begin() + d2);
+ for(impl_iterator it = it1; it != it2; ++it)
+ this->delete_node(*it);
+ impl.erase(it1, it2);
+ this->align_nodes(impl.begin() + d1, get_last_align());
+ }
+ return iterator(this->begin() + d1);
+ }
+
+ impl_iterator get_last_align()
+ {
+ return impl.end() - (ExtraPointers - 1);
+ }
+
+ const_impl_iterator get_last_align() const
+ {
+ return impl.cend() - (ExtraPointers - 1);
+ }
+
+ template<class AllocatorVersion>
+ iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
+ typename boost::interprocess_container::containers_detail::enable_if_c
+ <boost::interprocess_container::containers_detail::is_same<AllocatorVersion, allocator_v2>
+ ::value>::type * = 0)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ return priv_erase(first, last, allocator_v1());
+ }
+
+ static node_type_ptr_t node_ptr_cast(void_ptr p)
+ {
+ using boost::get_pointer;
+ return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static node_type_base_ptr_t node_base_ptr_cast(void_ptr p)
+ {
+ using boost::get_pointer;
+ return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static value_type& value(void_ptr p)
+ {
+ return node_ptr_cast(p)->value;
+ }
+
+ void initialize_end_node(size_type impl_capacity = 0)
+ {
+ if(impl.empty()){
+ impl.reserve(impl_capacity + ExtraPointers);
+ impl.resize (ExtraPointers, void_ptr(0));
+ impl[0] = &this->internal_data.end_node;
+ this->internal_data.end_node.up = &impl[0];
+ }
+ }
+
+ void readjust_end_node()
+ {
+ if(!this->impl.empty()){
+ void_ptr &end_node_ref = *(this->get_last_align()-1);
+ end_node_ref = this->get_end_node();
+ this->internal_data.end_node.up = &end_node_ref;
+ }
+ else{
+ this->internal_data.end_node.up = void_ptr(&this->internal_data.end_node.up);
+ }
+ }
+
+ node_type_ptr_t get_end_node() const
+ {
+ const node_type_base_t* cp = &this->internal_data.end_node;
+ node_type_base_t* p = const_cast<node_type_base_t*>(cp);
+ return node_ptr_cast(p);
+ }
+
+ template<class Iter>
+ void_ptr new_node(void_ptr up, Iter it)
+ {
+ node_type_ptr_t p = this->allocate_one();
+ try{
+ boost::interprocess_container::construct_in_place(&*p, it);
+ p->set_pointer(up);
+ }
+ catch(...){
+ this->deallocate_one(p);
+ throw;
+ }
+ return p;
+ }
+
+ void delete_node(void_ptr p)
+ {
+ node_type_ptr_t n(node_ptr_cast(p));
+ n->~node_type_t();
+ this->put_in_pool(n);
+ }
+
+ static void align_nodes(impl_iterator first,impl_iterator last)
+ {
+ while(first!=last){
+ node_ptr_cast(*first)->up = void_ptr(&*first);
+ ++first;
+ }
+ }
+
+ void insert_not_iter(const_iterator position, size_type n, const T& t)
+ {
+ typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->insert_iter(position, cvalue_iterator(t, n), cvalue_iterator(), std::forward_iterator_tag());
+ }
+
+ template <class InputIterator>
+ void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::true_)
+ {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category category;
+ this->insert_iter(position, first, last, category());
+ }
+
+ template <class InputIterator>
+ void insert_iter(const_iterator position,InputIterator first,InputIterator last,std::input_iterator_tag)
+ {
+ for(; first!=last; ++first){
+ this->insert(position, *first);
+ }
+ }
+
+ template <class InputIterator>
+ iterator insert_iter(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
+ {
+ size_type n = (size_type)std::distance(first,last);
+ difference_type d = position-this->cbegin();
+ if(n){
+ this->insert_iter_prolog(n, d);
+ const impl_iterator it(impl.begin() + d);
+ this->insert_iter_fwd(it, first, last, n);
+ //Fix the pointers for the newly allocated buffer
+ this->align_nodes(it + n, get_last_align());
+ }
+ return this->begin() + d;
+ }
+
+ template <class FwdIterator>
+ void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v1)
+ {
+ size_type i=0;
+ try{
+ while(first!=last){
+ *(it + i) = this->new_node(void_ptr((void*)(&*(it + i))), first);
+ ++first;
+ ++i;
+ }
+ }
+ catch(...){
+ impl.erase(it + i, it + n);
+ this->align_nodes(it + i, get_last_align());
+ throw;
+ }
+ }
+
+ template <class FwdIterator>
+ void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
+ {
+ multiallocation_chain mem(get_al().allocate_individual(n));
+
+ size_type i = 0;
+ node_type_ptr_t p = 0;
+ try{
+ while(first != last){
+ p = mem.front();
+ mem.pop_front();
+ //This can throw
+ boost::interprocess_container::construct_in_place(&*p, first);
+ p->set_pointer(void_ptr((void*)(&*(it + i))));
+ ++first;
+ *(it + i) = p;
+ ++i;
+ }
+ }
+ catch(...){
+ get_al().deallocate_one(p);
+ get_al().deallocate_many(boost::interprocess::move(mem));
+ impl.erase(it+i, it+n);
+ this->align_nodes(it+i,get_last_align());
+ throw;
+ }
+ }
+
+ template <class FwdIterator>
+ void insert_iter_fwd(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n)
+ {
+ size_type i = 0;
+ node_type_ptr_t p = 0;
+ try{
+ while(first != last){
+ p = get_from_pool();
+ if(!p){
+ insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
+ break;
+ }
+ //This can throw
+ boost::interprocess_container::construct_in_place(&*p, first);
+ p->set_pointer(void_ptr(&*(it+i)));
+ ++first;
+ *(it+i)=p;
+ ++i;
+ }
+ }
+ catch(...){
+ put_in_pool(p);
+ impl.erase(it+i,it+n);
+ this->align_nodes(it+i,get_last_align());
+ throw;
+ }
+ }
+
+ template <class InputIterator>
+ void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::false_)
+ {
+ this->insert_not_iter(position,first,last);
+ }
+
+ static void swap_impl(stable_vector& x,stable_vector& y)
+ {
+ using std::swap;
+ swap(x.get_al(),y.get_al());
+ swap(x.impl,y.impl);
+ swap(x.internal_data.pool_size, y.internal_data.pool_size);
+ x.readjust_end_node();
+ y.readjust_end_node();
+ }
+
+ #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+ bool invariant()const
+ {
+ if(impl.empty())
+ return !capacity() && !size();
+ if(get_end_node() != *(impl.end() - ExtraPointers)){
+ return false;
+ }
+ for(const_impl_iterator it=impl.begin(),it_end=get_last_align();it!=it_end;++it){
+ if(node_ptr_cast(*it)->up != &*it)
+ return false;
+ }
+ size_type n = capacity()-size();
+ const void_ptr &pool_head = impl.back();
+ size_type num_pool = 0;
+ node_type_ptr_t p = node_ptr_cast(pool_head);
+ while(p){
+ ++num_pool;
+ p = p->up;
+ }
+ return n >= num_pool;
+ }
+
+ class invariant_checker:private boost::noncopyable
+ {
+ const stable_vector* p;
+ public:
+ invariant_checker(const stable_vector& v):p(&v){}
+ ~invariant_checker(){BOOST_ASSERT(p->invariant());}
+ void touch(){}
+ };
+ #endif
+
+ struct ebo_holder
+ : node_allocator_type
+ {
+ ebo_holder(const allocator_type &a)
+ : node_allocator_type(a), pool_size(0), end_node()
+ {
+ end_node.set_pointer(void_ptr(&end_node.up));
+ }
+ size_type pool_size;
+ node_type_base_t end_node;
+ } internal_data;
+
+ node_allocator_type &get_al() { return internal_data; }
+ const node_allocator_type &get_al() const { return internal_data; }
+
+ impl_type impl;
+ /// @endcond
+};
+
+template <typename T,typename Allocator>
+bool operator==(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
+{
+ return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
+}
+
+template <typename T,typename Allocator>
+bool operator< (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
+{
+ return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+}
+
+template <typename T,typename Allocator>
+bool operator!=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
+{
+ return !(x==y);
+}
+
+template <typename T,typename Allocator>
+bool operator> (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
+{
+ return y<x;
+}
+
+template <typename T,typename Allocator>
+bool operator>=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
+{
+ return !(x<y);
+}
+
+template <typename T,typename Allocator>
+bool operator<=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
+{
+ return !(x>y);
+}
+
+// specialized algorithms:
+
+template <typename T, typename Allocator>
+void swap(stable_vector<T,Allocator>& x,stable_vector<T,Allocator>& y)
+{
+ x.swap(y);
+}
+
+/// @cond
+
+#undef STABLE_VECTOR_CHECK_INVARIANT
+
+/// @endcond
+
+}}
+
+#endif
Added: trunk/boost/interprocess/containers/container/string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/string.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,2320 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2008
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+
+#ifndef BOOST_CONTAINERS_STRING_HPP
+#define BOOST_CONTAINERS_STRING_HPP
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/iterators.hpp>
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/interprocess/containers/container/detail/allocation_type.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/static_assert.hpp>
+
+#include <functional>
+#include <string>
+#include <stdexcept>
+#include <utility>
+#include <iterator>
+#include <memory>
+#include <algorithm>
+#include <iosfwd>
+#include <istream>
+#include <ostream>
+#include <ios>
+#include <locale>
+#include <cstddef>
+#include <climits>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+namespace containers_detail {
+// ------------------------------------------------------------
+// Class basic_string_base.
+
+// basic_string_base is a helper class that makes it it easier to write
+// an exception-safe version of basic_string. The constructor allocates,
+// but does not initialize, a block of memory. The destructor
+// deallocates, but does not destroy elements within, a block of
+// memory. The destructor assumes that the memory either is the internal buffer,
+// or else points to a block of memory that was allocated using _String_base's
+// allocator and whose size is this->m_storage.
+template <class A>
+class basic_string_base
+{
+ basic_string_base();
+ basic_string_base(basic_string_base&);
+ basic_string_base & operator=(basic_string_base&);
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_string_base)
+
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::value_type value_type;
+ typedef typename A::size_type size_type;
+
+ basic_string_base(const allocator_type& a)
+ : members_(a)
+ { init(); }
+
+ basic_string_base(const allocator_type& a, std::size_t n)
+ : members_(a)
+ {
+ this->init();
+ this->allocate_initial_block(n);
+ }
+
+ basic_string_base(BOOST_INTERPROCESS_RV_REF(basic_string_base) b)
+ : members_(b.members_)
+ {
+ init();
+ this->swap(b);
+ }
+
+ ~basic_string_base()
+ {
+ this->deallocate_block();
+ if(!this->is_short()){
+ static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
+ }
+ }
+
+ private:
+
+ //This is the structure controlling a long string
+ struct long_t
+ {
+ size_type is_short : 1;
+ size_type length : (sizeof(size_type)*CHAR_BIT - 1);
+ size_type storage;
+ pointer start;
+
+ long_t()
+ {}
+
+ long_t(const long_t &other)
+ {
+ this->is_short = other.is_short;
+ length = other.length;
+ storage = other.storage;
+ start = other.start;
+ }
+
+ long_t &operator =(const long_t &other)
+ {
+ this->is_short = other.is_short;
+ length = other.length;
+ storage = other.storage;
+ start = other.start;
+ return *this;
+ }
+ };
+
+ //This basic type should have the same alignment as long_t
+//iG typedef typename type_with_alignment<containers_detail::alignment_of<long_t>::value>::type
+// long_alignment_type;
+ typedef void *long_alignment_type;
+ BOOST_STATIC_ASSERT((containers_detail::alignment_of<long_alignment_type>::value %
+ containers_detail::alignment_of<long_t>::value) == 0);
+
+
+ //This type is the first part of the structure controlling a short string
+ //The "data" member stores
+ struct short_header
+ {
+ unsigned char is_short : 1;
+ unsigned char length : (CHAR_BIT - 1);
+ };
+
+ //This type has the same alignment and size as long_t but it's POD
+ //so, unlike long_t, it can be placed in a union
+ struct long_raw_t
+ {
+ long_alignment_type a;
+ unsigned char b[sizeof(long_t) - sizeof(long_alignment_type)];
+ };
+
+ protected:
+ static const size_type MinInternalBufferChars = 8;
+ static const size_type AlignmentOfValueType =
+ alignment_of<value_type>::value;
+ static const size_type ShortDataOffset =
+ containers_detail::ct_rounded_size<sizeof(short_header), AlignmentOfValueType>::value;
+ static const size_type ZeroCostInternalBufferChars =
+ (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
+ static const size_type UnalignedFinalInternalBufferChars =
+ (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
+ ZeroCostInternalBufferChars : MinInternalBufferChars;
+
+ struct short_t
+ {
+ short_header h;
+ value_type data[UnalignedFinalInternalBufferChars];
+ };
+
+ union repr_t
+ {
+ long_raw_t r;
+ short_t s;
+
+ short_t &short_repr() const
+ { return *const_cast<short_t *>(&s); }
+
+ long_t &long_repr() const
+ { return *static_cast<long_t*>(const_cast<void*>(static_cast<const void*>(&r))); }
+ };
+
+ struct members_holder
+ : public A
+ {
+ members_holder(const A &a)
+ : A(a)
+ {}
+
+ repr_t m_repr;
+ } members_;
+
+ const A &alloc() const
+ { return members_; }
+
+ A &alloc()
+ { return members_; }
+
+ static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
+
+ private:
+
+ static const size_type MinAllocation = InternalBufferChars*2;
+
+ protected:
+ bool is_short() const
+ { return static_cast<bool>(this->members_.m_repr.s.h.is_short != 0); }
+
+ void is_short(bool yes)
+ {
+ if(yes && !this->is_short()){
+ static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
+ }
+ else{
+ new(static_cast<void*>(&this->members_.m_repr.r))long_t();
+ }
+ this->members_.m_repr.s.h.is_short = yes;
+ }
+
+ private:
+ void init()
+ {
+ this->members_.m_repr.s.h.is_short = 1;
+ this->members_.m_repr.s.h.length = 0;
+ }
+
+ protected:
+
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::interprocess_container::containers_detail::version<A>::value> alloc_version;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, pointer reuse = 0)
+ {
+ if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
+ reuse = pointer(0);
+ command &= ~(expand_fwd | expand_bwd);
+ }
+ return this->allocation_command
+ (command, limit_size, preferred_size, received_size, reuse, alloc_version());
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ const pointer &reuse,
+ allocator_v1)
+ {
+ (void)limit_size;
+ (void)reuse;
+ if(!(command & allocate_new))
+ return std::pair<pointer, bool>(pointer(0), 0);
+ received_size = preferred_size;
+ return std::make_pair(this->alloc().allocate(received_size), false);
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ pointer reuse,
+ allocator_v2)
+ {
+ return this->alloc().allocation_command(command, limit_size, preferred_size,
+ received_size, reuse);
+ }
+
+ size_type next_capacity(size_type additional_objects) const
+ { return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects); }
+
+ void deallocate(pointer p, std::size_t n)
+ {
+ if (p && (n > InternalBufferChars))
+ this->alloc().deallocate(p, n);
+ }
+
+ void construct(pointer p, const value_type &value = value_type())
+ { new((void*)containers_detail::get_pointer(p)) value_type(value); }
+
+ void destroy(pointer p, size_type n)
+ {
+ for(; n--; ++p)
+ containers_detail::get_pointer(p)->~value_type();
+ }
+
+ void destroy(pointer p)
+ { containers_detail::get_pointer(p)->~value_type(); }
+
+ void allocate_initial_block(std::size_t n)
+ {
+ if (n <= this->max_size()) {
+ if(n > InternalBufferChars){
+ size_type new_cap = this->next_capacity(n);
+ pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
+ this->is_short(false);
+ this->priv_addr(p);
+ this->priv_size(0);
+ this->priv_storage(new_cap);
+ }
+ }
+ else
+ throw_length_error();
+ }
+
+ void deallocate_block()
+ { this->deallocate(this->priv_addr(), this->priv_storage()); }
+
+ std::size_t max_size() const
+ { return this->alloc().max_size() - 1; }
+
+ // Helper functions for exception handling.
+ void throw_length_error() const
+ { throw(std::length_error("basic_string")); }
+
+ void throw_out_of_range() const
+ { throw(std::out_of_range("basic_string")); }
+
+ protected:
+ size_type priv_capacity() const
+ { return this->priv_storage() - 1; }
+
+ pointer priv_addr() const
+ { return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start; }
+
+ void priv_addr(pointer addr)
+ { this->members_.m_repr.long_repr().start = addr; }
+
+ size_type priv_storage() const
+ { return this->is_short() ? InternalBufferChars : this->members_.m_repr.long_repr().storage; }
+
+ void priv_storage(size_type storage)
+ {
+ if(!this->is_short())
+ this->members_.m_repr.long_repr().storage = storage;
+ }
+
+ size_type priv_size() const
+ { return this->is_short() ? this->members_.m_repr.short_repr().h.length : this->members_.m_repr.long_repr().length; }
+
+ void priv_size(size_type sz)
+ {
+ if(this->is_short())
+ this->members_.m_repr.s.h.length = (unsigned char)sz;
+ else
+ this->members_.m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
+ }
+
+ void swap(basic_string_base& other)
+ {
+ if(this->is_short()){
+ if(other.is_short()){
+ std::swap(this->members_.m_repr, other.members_.m_repr);
+ }
+ else{
+ repr_t copied(this->members_.m_repr);
+ this->members_.m_repr.long_repr() = other.members_.m_repr.long_repr();
+ other.members_.m_repr = copied;
+ }
+ }
+ else{
+ if(other.is_short()){
+ repr_t copied(other.members_.m_repr);
+ other.members_.m_repr.long_repr() = this->members_.m_repr.long_repr();
+ this->members_.m_repr = copied;
+ }
+ else{
+ std::swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+ }
+ }
+
+ allocator_type & this_al = this->alloc(), &other_al = other.alloc();
+ if(this_al != other_al){
+ containers_detail::do_swap(this_al, other_al);
+ }
+ }
+};
+
+} //namespace containers_detail {
+
+/// @endcond
+
+//! The basic_string class represents a Sequence of characters. It contains all the
+//! usual operations of a Sequence, and, additionally, it contains standard string
+//! operations such as search and concatenation.
+//!
+//! The basic_string class is parameterized by character type, and by that type's
+//! Character Traits.
+//!
+//! This class has performance characteristics very much like vector<>, meaning,
+//! for example, that it does not perform reference-count or copy-on-write, and that
+//! concatenation of two strings is an O(N) operation.
+//!
+//! Some of basic_string's member functions use an unusual method of specifying positions
+//! and ranges. In addition to the conventional method using iterators, many of
+//! basic_string's member functions use a single value pos of type size_type to represent a
+//! position (in which case the position is begin() + pos, and many of basic_string's
+//! member functions use two values, pos and n, to represent a range. In that case pos is
+//! the beginning of the range and n is its size. That is, the range is
+//! [begin() + pos, begin() + pos + n).
+//!
+//! Note that the C++ standard does not specify the complexity of basic_string operations.
+//! In this implementation, basic_string has performance characteristics very similar to
+//! those of vector: access to a single character is O(1), while copy and concatenation
+//! are O(N).
+//!
+//! In this implementation, begin(),
+//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
+//! In this implementation, iterators are only invalidated by member functions that
+//! explicitly change the string's contents.
+template <class CharT, class Traits, class A>
+class basic_string
+ : private containers_detail::basic_string_base<A>
+{
+ /// @cond
+ private:
+ typedef containers_detail::basic_string_base<A> base_t;
+ static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
+
+ protected:
+ // A helper class to use a char_traits as a function object.
+
+ template <class Tr>
+ struct Eq_traits
+ : public std::binary_function<typename Tr::char_type,
+ typename Tr::char_type,
+ bool>
+ {
+ bool operator()(const typename Tr::char_type& x,
+ const typename Tr::char_type& y) const
+ { return Tr::eq(x, y); }
+ };
+
+ template <class Tr>
+ struct Not_within_traits
+ : public std::unary_function<typename Tr::char_type, bool>
+ {
+ typedef const typename Tr::char_type* Pointer;
+ const Pointer m_first;
+ const Pointer m_last;
+
+ Not_within_traits(Pointer f, Pointer l)
+ : m_first(f), m_last(l) {}
+
+ bool operator()(const typename Tr::char_type& x) const
+ {
+ return std::find_if(m_first, m_last,
+ std::bind1st(Eq_traits<Tr>(), x)) == m_last;
+ }
+ };
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_string)
+
+ //! The allocator type
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+ //! The type of object, CharT, stored in the string
+ typedef CharT value_type;
+ //! The second template parameter Traits
+ typedef Traits traits_type;
+ //! Pointer to CharT
+ typedef typename A::pointer pointer;
+ //! Const pointer to CharT
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to CharT
+ typedef typename A::reference reference;
+ //! Const reference to CharT
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! Iterator used to iterate through a string. It's a Random Access Iterator
+ typedef pointer iterator;
+ //! Const iterator used to iterate through a string. It's a Random Access Iterator
+ typedef const_pointer const_iterator;
+ //! Iterator used to iterate backwards through a string
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ //! Const iterator used to iterate backwards through a string
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ //! The largest possible value of type size_type. That is, size_type(-1).
+ static const size_type npos;
+
+ /// @cond
+ private:
+ typedef constant_iterator<CharT, difference_type> cvalue_iterator;
+ /// @endcond
+
+ public: // Constructor, destructor, assignment.
+ /// @cond
+ struct reserve_t {};
+ /// @endcond
+
+ basic_string(reserve_t, std::size_t n,
+ const allocator_type& a = allocator_type())
+ : base_t(a, n + 1)
+ { this->priv_terminate_string(); }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ explicit basic_string(const allocator_type& a = allocator_type())
+ : base_t(a, InternalBufferChars)
+ { this->priv_terminate_string(); }
+
+ //! <b>Effects</b>: Copy constructs a basic_string.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ basic_string(const basic_string& s)
+ : base_t(s.alloc())
+ { this->priv_range_initialize(s.begin(), s.end()); }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ basic_string(BOOST_INTERPROCESS_RV_REF(basic_string) s)
+ : base_t(boost::interprocess::move((base_t&)s))
+ {}
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by a specific number of characters of the s string.
+ basic_string(const basic_string& s, size_type pos, size_type n = npos,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ {
+ if (pos > s.size())
+ this->throw_out_of_range();
+ else
+ this->priv_range_initialize
+ (s.begin() + pos, s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
+ }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by a specific number of characters of the s c-string.
+ basic_string(const CharT* s, size_type n,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->priv_range_initialize(s, s + n); }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by the null-terminated s c-string.
+ basic_string(const CharT* s,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->priv_range_initialize(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by n copies of c.
+ basic_string(size_type n, CharT c,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ {
+ this->priv_range_initialize(cvalue_iterator(c, n),
+ cvalue_iterator());
+ }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and a range of iterators.
+ template <class InputIterator>
+ basic_string(InputIterator f, InputIterator l,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIterator, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_initialize_dispatch(f, l, Result());
+ }
+
+ //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ ~basic_string()
+ {}
+
+ //! <b>Effects</b>: Copy constructs a string.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ basic_string& operator=(const basic_string& s)
+ {
+ if (&s != this)
+ this->assign(s.begin(), s.end());
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ basic_string& operator=(BOOST_INTERPROCESS_RV_REF(basic_string) ms)
+ {
+ basic_string &s = ms;
+ if (&s != this){
+ this->swap(s);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assignment from a null-terminated c-string.
+ basic_string& operator=(const CharT* s)
+ { return this->assign(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Assignment from character.
+ basic_string& operator=(CharT c)
+ { return this->assign(static_cast<size_type>(1), c); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return this->priv_addr(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->priv_addr(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return this->priv_addr() + this->priv_size(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->priv_addr() + this->priv_size(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->priv_addr() + this->priv_size()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator(this->priv_addr() + this->priv_size()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(this->priv_addr()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return const_reverse_iterator(this->priv_addr()); }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return this->alloc(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->priv_size(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type length() const
+ { return this->size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return base_t::max_size(); }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n, CharT c)
+ {
+ if (n <= size())
+ this->erase(this->begin() + n, this->end());
+ else
+ this->append(n - this->size(), c);
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n)
+ { resize(n, this->priv_null()); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ void reserve(size_type res_arg)
+ {
+ if (res_arg > this->max_size())
+ this->throw_length_error();
+
+ if (this->capacity() < res_arg){
+ size_type n = containers_detail::max_value(res_arg, this->size()) + 1;
+ size_type new_cap = this->next_capacity(n);
+ pointer new_start = this->allocation_command
+ (allocate_new, n, new_cap, new_cap).first;
+ size_type new_length = 0;
+
+ new_length += priv_uninitialized_copy
+ (this->priv_addr(), this->priv_addr() + this->priv_size(), new_start);
+ this->priv_construct_null(new_start + new_length);
+ this->deallocate_block();
+ this->is_short(false);
+ this->priv_addr(new_start);
+ this->priv_size(new_length);
+ this->priv_storage(new_cap);
+ }
+ }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return this->priv_capacity(); }
+
+ //! <b>Effects</b>: Erases all the elements of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the vector.
+ void clear()
+ {
+ if (!empty()) {
+ Traits::assign(*this->priv_addr(), this->priv_null());
+ this->priv_size(0);
+ }
+ }
+
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->priv_size(); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n)
+ { return *(this->priv_addr() + n); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n) const
+ { return *(this->priv_addr() + n); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n) {
+ if (n >= size())
+ this->throw_out_of_range();
+ return *(this->priv_addr() + n);
+ }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n) const {
+ if (n >= size())
+ this->throw_out_of_range();
+ return *(this->priv_addr() + n);
+ }
+
+ //! <b>Effects</b>: Appends string s to *this.
+ basic_string& operator+=(const basic_string& s)
+ { return this->append(s); }
+
+ //! <b>Effects</b>: Appends c-string s to *this.
+ basic_string& operator+=(const CharT* s)
+ { return this->append(s); }
+
+ //! <b>Effects</b>: Appends character c to *this.
+ basic_string& operator+=(CharT c)
+ { this->push_back(c); return *this; }
+
+ //! <b>Effects</b>: Appends string s to *this.
+ basic_string& append(const basic_string& s)
+ { return this->append(s.begin(), s.end()); }
+
+ //! <b>Effects</b>: Appends the range [pos, pos + n) from string s to *this.
+ basic_string& append(const basic_string& s, size_type pos, size_type n)
+ {
+ if (pos > s.size())
+ this->throw_out_of_range();
+ return this->append(s.begin() + pos,
+ s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
+ }
+
+ //! <b>Effects</b>: Appends the range [s, s + n) from c-string s to *this.
+ basic_string& append(const CharT* s, size_type n)
+ { return this->append(s, s + n); }
+
+ //! <b>Effects</b>: Appends the c-string s to *this.
+ basic_string& append(const CharT* s)
+ { return this->append(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Appends the n times the character c to *this.
+ basic_string& append(size_type n, CharT c)
+ { return this->append(cvalue_iterator(c, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Appends the range [first, last) *this.
+ template <class InputIter>
+ basic_string& append(InputIter first, InputIter last)
+ { this->insert(this->end(), first, last); return *this; }
+
+ //! <b>Effects</b>: Inserts a copy of c at the end of the vector.
+ void push_back(CharT c)
+ {
+ if (this->priv_size() < this->capacity()){
+ this->priv_construct_null(this->priv_addr() + (this->priv_size() + 1));
+ Traits::assign(this->priv_addr()[this->priv_size()], c);
+ this->priv_size(this->priv_size()+1);
+ }
+ else{
+ //No enough memory, insert a new object at the end
+ this->append((size_type)1, c);
+ }
+ }
+
+ //! <b>Effects</b>: Removes the last element from the vector.
+ void pop_back()
+ {
+ Traits::assign(this->priv_addr()[this->priv_size()-1], this->priv_null());
+ this->priv_size(this->priv_size()-1);;
+ }
+
+ //! <b>Effects</b>: Assigns the value s to *this.
+ basic_string& assign(const basic_string& s)
+ { return this->operator=(s); }
+
+ //! <b>Effects</b>: Moves the resources from ms *this.
+ basic_string& assign(BOOST_INTERPROCESS_RV_REF(basic_string) ms)
+ { return this->operator=(ms);}
+
+ //! <b>Effects</b>: Assigns the range [pos, pos + n) from s to *this.
+ basic_string& assign(const basic_string& s,
+ size_type pos, size_type n) {
+ if (pos > s.size())
+ this->throw_out_of_range();
+ return this->assign(s.begin() + pos,
+ s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
+ }
+
+ //! <b>Effects</b>: Assigns the range [s, s + n) from s to *this.
+ basic_string& assign(const CharT* s, size_type n)
+ { return this->assign(s, s + n); }
+
+ //! <b>Effects</b>: Assigns the c-string s to *this.
+ basic_string& assign(const CharT* s)
+ { return this->assign(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Assigns the character c n-times to *this.
+ basic_string& assign(size_type n, CharT c)
+ { return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Assigns the range [first, last) to *this.
+ template <class InputIter>
+ basic_string& assign(InputIter first, InputIter last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIter, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ return this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Effects</b>: Assigns the range [f, l) to *this.
+ basic_string& assign(const CharT* f, const CharT* l)
+ {
+ const std::ptrdiff_t n = l - f;
+ if (static_cast<size_type>(n) <= size()) {
+ Traits::copy(containers_detail::get_pointer(this->priv_addr()), f, n);
+ this->erase(this->priv_addr() + n, this->priv_addr() + this->priv_size());
+ }
+ else {
+ Traits::copy(containers_detail::get_pointer(this->priv_addr()), f, this->priv_size());
+ this->append(f + this->priv_size(), l);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Inserts the string s before pos.
+ basic_string& insert(size_type pos, const basic_string& s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ if (this->size() > this->max_size() - s.size())
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, s.begin(), s.end());
+ return *this;
+ }
+
+ //! <b>Effects</b>: Inserts the range [pos, pos + n) from string s before pos.
+ basic_string& insert(size_type pos, const basic_string& s,
+ size_type beg, size_type n)
+ {
+ if (pos > this->size() || beg > s.size())
+ this->throw_out_of_range();
+ size_type len = containers_detail::min_value(n, s.size() - beg);
+ if (this->size() > this->max_size() - len)
+ this->throw_length_error();
+ const CharT *beg_ptr = containers_detail::get_pointer(s.begin()) + beg;
+ const CharT *end_ptr = beg_ptr + len;
+ this->insert(this->priv_addr() + pos, beg_ptr, end_ptr);
+ return *this;
+ }
+
+ //! <b>Effects</b>: Inserts the range [s, s + n) before pos.
+ basic_string& insert(size_type pos, const CharT* s, size_type n)
+ {
+ if (pos > this->size())
+ this->throw_out_of_range();
+ if (this->size() > this->max_size() - n)
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, s, s + n);
+ return *this;
+ }
+
+ //! <b>Effects</b>: Inserts the c-string s before pos.
+ basic_string& insert(size_type pos, const CharT* s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ size_type len = Traits::length(s);
+ if (this->size() > this->max_size() - len)
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, s, s + len);
+ return *this;
+ }
+
+ //! <b>Effects</b>: Inserts the character c n-times before pos.
+ basic_string& insert(size_type pos, size_type n, CharT c)
+ {
+ if (pos > this->size())
+ this->throw_out_of_range();
+ if (this->size() > this->max_size() - n)
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, n, c);
+ return *this;
+ }
+
+ //! <b>Effects</b>: Inserts the character c before position.
+ iterator insert(iterator position, CharT c)
+ {
+ size_type new_offset = position - this->priv_addr() + 1;
+ this->insert(position, cvalue_iterator(c, 1),
+ cvalue_iterator());
+ return this->priv_addr() + new_offset;
+ }
+
+ //! <b>Effects</b>: Inserts the character c n-times before position.
+ void insert(iterator position, std::size_t n, CharT c)
+ {
+ this->insert(position, cvalue_iterator(c, n),
+ cvalue_iterator());
+ }
+
+ //! <b>Effects</b>: Inserts the range [first, last) before position.
+ template <class InputIter>
+ void insert(iterator p, InputIter first, InputIter last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIter, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(p, first, last, Result());
+ }
+
+ //! <b>Effects</b>: Inserts the range [pos, pos + n).
+ basic_string& erase(size_type pos = 0, size_type n = npos)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ erase(this->priv_addr() + pos, this->priv_addr() + pos + containers_detail::min_value(n, size() - pos));
+ return *this;
+ }
+
+ //! <b>Effects</b>: Erases the character pointed by position.
+ iterator erase(iterator position)
+ {
+ // The move includes the terminating null.
+ Traits::move(containers_detail::get_pointer(position),
+ containers_detail::get_pointer(position + 1),
+ this->priv_size() - (position - this->priv_addr()));
+ this->priv_size(this->priv_size()-1);
+ return position;
+ }
+
+ //! <b>Effects</b>: Erases the range [first, last).
+ iterator erase(iterator first, iterator last)
+ {
+ if (first != last) { // The move includes the terminating null.
+ size_type num_erased = last - first;
+ Traits::move(containers_detail::get_pointer(first),
+ containers_detail::get_pointer(last),
+ (this->priv_size() + 1)-(last - this->priv_addr()));
+ size_type new_length = this->priv_size() - num_erased;
+ this->priv_size(new_length);
+ }
+ return first;
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with the string s.
+ basic_string& replace(size_type pos, size_type n,
+ const basic_string& s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n, size() - pos);
+ if (this->size() - len >= this->max_size() - s.size())
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
+ s.begin(), s.end());
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with a substring of s.
+ basic_string& replace(size_type pos1, size_type n1,
+ const basic_string& s,
+ size_type pos2, size_type n2)
+ {
+ if (pos1 > size() || pos2 > s.size())
+ this->throw_out_of_range();
+ const size_type len1 = containers_detail::min_value(n1, size() - pos1);
+ const size_type len2 = containers_detail::min_value(n2, s.size() - pos2);
+ if (this->size() - len1 >= this->max_size() - len2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len1,
+ s.priv_addr() + pos2, s.priv_addr() + pos2 + len2);
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with the first n1 characters of s.
+ basic_string& replace(size_type pos, size_type n1,
+ const CharT* s, size_type n2)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos);
+ if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
+ s, s + n2);
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with a null-terminated character array.
+ basic_string& replace(size_type pos, size_type n1,
+ const CharT* s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos);
+ const size_type n2 = Traits::length(s);
+ if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
+ s, s + Traits::length(s));
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with n1 copies of c.
+ basic_string& replace(size_type pos, size_type n1,
+ size_type n2, CharT c)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos);
+ if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len, n2, c);
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with the string s.
+ basic_string& replace(iterator first, iterator last,
+ const basic_string& s)
+ { return this->replace(first, last, s.begin(), s.end()); }
+
+ //! <b>Effects</b>: Replaces a substring of *this with the first n characters of s.
+ basic_string& replace(iterator first, iterator last,
+ const CharT* s, size_type n)
+ { return this->replace(first, last, s, s + n); }
+
+ //! <b>Effects</b>: Replaces a substring of *this with a null-terminated character array.
+ basic_string& replace(iterator first, iterator last,
+ const CharT* s)
+ { return this->replace(first, last, s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Replaces a substring of *this with n copies of c.
+ basic_string& replace(iterator first, iterator last,
+ size_type n, CharT c)
+ {
+ const size_type len = static_cast<size_type>(last - first);
+ if (len >= n) {
+ Traits::assign(containers_detail::get_pointer(first), n, c);
+ erase(first + n, last);
+ }
+ else {
+ Traits::assign(containers_detail::get_pointer(first), len, c);
+ insert(last, n - len, c);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Replaces a substring of *this with the range [f, l)
+ template <class InputIter>
+ basic_string& replace(iterator first, iterator last,
+ InputIter f, InputIter l)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIter, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ return this->priv_replace_dispatch(first, last, f, l, Result());
+ }
+
+ //! <b>Effects</b>: Copies a substring of *this to a buffer.
+ size_type copy(CharT* s, size_type n, size_type pos = 0) const
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n, size() - pos);
+ Traits::copy(s, containers_detail::get_pointer(this->priv_addr() + pos), len);
+ return len;
+ }
+
+ //! <b>Effects</b>: Swaps the contents of two strings.
+ void swap(basic_string& x)
+ { base_t::swap(x); }
+
+ //! <b>Returns</b>: Returns a pointer to a null-terminated array of characters
+ //! representing the string's contents. For any string s it is guaranteed
+ //! that the first s.size() characters in the array pointed to by s.c_str()
+ //! are equal to the character in s, and that s.c_str()[s.size()] is a null
+ //! character. Note, however, that it not necessarily the first null character.
+ //! Characters within a string are permitted to be null.
+ const CharT* c_str() const
+ { return containers_detail::get_pointer(this->priv_addr()); }
+
+ //! <b>Returns</b>: Returns a pointer to an array of characters, not necessarily
+ //! null-terminated, representing the string's contents. data() is permitted,
+ //! but not required, to be identical to c_str(). The first size() characters
+ //! of that array are guaranteed to be identical to the characters in *this.
+ //! The return value of data() is never a null pointer, even if size() is zero.
+ const CharT* data() const
+ { return containers_detail::get_pointer(this->priv_addr()); }
+
+ //! <b>Effects</b>: Searches for s as a substring of *this, beginning at
+ //! character pos of *this.
+ size_type find(const basic_string& s, size_type pos = 0) const
+ { return find(s.c_str(), pos, s.size()); }
+
+ //! <b>Effects</b>: Searches for a null-terminated character array as a
+ //! substring of *this, beginning at character pos of *this.
+ size_type find(const CharT* s, size_type pos = 0) const
+ { return find(s, pos, Traits::length(s)); }
+
+ //! <b>Effects</b>: Searches for the first n characters of s as a substring
+ //! of *this, beginning at character pos of *this.
+ size_type find(const CharT* s, size_type pos, size_type n) const
+ {
+ if (pos + n > size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const const_iterator result =
+ std::search(containers_detail::get_pointer(this->priv_addr() + pos),
+ containers_detail::get_pointer(finish),
+ s, s + n, Eq_traits<Traits>());
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches for the character c, beginning at character
+ //! position pos.
+ size_type find(CharT c, size_type pos = 0) const
+ {
+ if (pos >= size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const const_iterator result =
+ std::find_if(this->priv_addr() + pos, finish,
+ std::bind2nd(Eq_traits<Traits>(), c));
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches backward for s as a substring of *this,
+ //! beginning at character position min(pos, size())
+ size_type rfind(const basic_string& s, size_type pos = npos) const
+ { return rfind(s.c_str(), pos, s.size()); }
+
+ //! <b>Effects</b>: Searches backward for a null-terminated character array
+ //! as a substring of *this, beginning at character min(pos, size())
+ size_type rfind(const CharT* s, size_type pos = npos) const
+ { return rfind(s, pos, Traits::length(s)); }
+
+ //! <b>Effects</b>: Searches backward for the first n characters of s as a
+ //! substring of *this, beginning at character position min(pos, size()).
+ size_type rfind(const CharT* s, size_type pos, size_type n) const
+ {
+ const std::size_t len = size();
+
+ if (n > len)
+ return npos;
+ else if (n == 0)
+ return containers_detail::min_value(len, pos);
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - n, pos) + n;
+ const const_iterator result = find_end(begin(), last,
+ s, s + n,
+ Eq_traits<Traits>());
+ return result != last ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches backward for a null-terminated character array
+ //! as a substring of *this, beginning at character min(pos, size()).
+ size_type rfind(CharT c, size_type pos = npos) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
+ const_reverse_iterator rresult =
+ std::find_if(const_reverse_iterator(last), rend(),
+ std::bind2nd(Eq_traits<Traits>(), c));
+ return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is equal to any character within s.
+ size_type find_first_of(const basic_string& s, size_type pos = 0) const
+ { return find_first_of(s.c_str(), pos, s.size()); }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is equal to any character within s.
+ size_type find_first_of(const CharT* s, size_type pos = 0) const
+ { return find_first_of(s, pos, Traits::length(s)); }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is equal to any character within the first n characters of s.
+ size_type find_first_of(const CharT* s, size_type pos,
+ size_type n) const
+ {
+ if (pos >= size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const_iterator result = std::find_first_of(this->priv_addr() + pos, finish,
+ s, s + n,
+ Eq_traits<Traits>());
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is equal to c.
+ size_type find_first_of(CharT c, size_type pos = 0) const
+ { return find(c, pos); }
+
+ //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
+ //! for the first character that is equal to any character within s.
+ size_type find_last_of(const basic_string& s,
+ size_type pos = npos) const
+ { return find_last_of(s.c_str(), pos, s.size()); }
+
+ //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()), for
+ //! the first character that is equal to any character within s.
+ size_type find_last_of(const CharT* s, size_type pos = npos) const
+ { return find_last_of(s, pos, Traits::length(s)); }
+
+ //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
+ //! for the first character that is equal to any character within the first n
+ //! characters of s.
+ size_type find_last_of(const CharT* s, size_type pos, size_type n) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = this->priv_addr() + containers_detail::min_value(len - 1, pos) + 1;
+ const const_reverse_iterator rresult =
+ std::find_first_of(const_reverse_iterator(last), rend(),
+ s, s + n,
+ Eq_traits<Traits>());
+ return rresult != rend() ? (rresult.base() - 1) - this->priv_addr() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()), for
+ //! the first character that is equal to c.
+ size_type find_last_of(CharT c, size_type pos = npos) const
+ { return rfind(c, pos); }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is not equal to any character within s.
+ size_type find_first_not_of(const basic_string& s,
+ size_type pos = 0) const
+ { return find_first_not_of(s.c_str(), pos, s.size()); }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is not equal to any character within s.
+ size_type find_first_not_of(const CharT* s, size_type pos = 0) const
+ { return find_first_not_of(s, pos, Traits::length(s)); }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is not equal to any character within the first n
+ //! characters of s.
+ size_type find_first_not_of(const CharT* s, size_type pos,
+ size_type n) const
+ {
+ if (pos > size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const_iterator result = std::find_if(this->priv_addr() + pos, finish,
+ Not_within_traits<Traits>(s, s + n));
+ return result != finish ? result - this->priv_addr() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
+ //! character that is not equal to c.
+ size_type find_first_not_of(CharT c, size_type pos = 0) const
+ {
+ if (pos > size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const_iterator result
+ = std::find_if(this->priv_addr() + pos, finish,
+ std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
+ //! for the first character that is not equal to any character within s.
+ size_type find_last_not_of(const basic_string& s,
+ size_type pos = npos) const
+ { return find_last_not_of(s.c_str(), pos, s.size()); }
+
+ //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()),
+ //! for the first character that is not equal to any character within s.
+ size_type find_last_not_of(const CharT* s, size_type pos = npos) const
+ { return find_last_not_of(s, pos, Traits::length(s)); }
+
+ //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
+ //! for the first character that is not equal to any character within the first
+ //! n characters of s.
+ size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
+ const const_reverse_iterator rresult =
+ std::find_if(const_reverse_iterator(last), rend(),
+ Not_within_traits<Traits>(s, s + n));
+ return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()),
+ //! for the first character that is not equal to c.
+ size_type find_last_not_of(CharT c, size_type pos = npos) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
+ const_reverse_iterator rresult =
+ std::find_if(const_reverse_iterator(last), rend(),
+ std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
+ return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Returns a substring of *this.
+ basic_string substr(size_type pos = 0, size_type n = npos) const
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ return basic_string(this->priv_addr() + pos,
+ this->priv_addr() + pos + containers_detail::min_value(n, size() - pos), this->alloc());
+ }
+
+ //! <b>Effects</b>: Three-way lexicographical comparison of s and *this.
+ int compare(const basic_string& s) const
+ { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s.priv_addr(), s.priv_addr() + s.priv_size()); }
+
+ //! <b>Effects</b>: Three-way lexicographical comparison of s and a substring
+ //! of *this.
+ int compare(size_type pos1, size_type n1, const basic_string& s) const
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ return s_compare(this->priv_addr() + pos1,
+ this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
+ s.priv_addr(), s.priv_addr() + s.priv_size());
+ }
+
+ //! <b>Effects</b>: Three-way lexicographical comparison of a substring of s
+ //! and a substring of *this.
+ int compare(size_type pos1, size_type n1,
+ const basic_string& s,
+ size_type pos2, size_type n2) const {
+ if (pos1 > size() || pos2 > s.size())
+ this->throw_out_of_range();
+ return s_compare(this->priv_addr() + pos1,
+ this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
+ s.priv_addr() + pos2,
+ s.priv_addr() + pos2 + containers_detail::min_value(n2, size() - pos2));
+ }
+
+ //! <b>Effects</b>: Three-way lexicographical comparison of s and *this.
+ int compare(const CharT* s) const
+ { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s, s + Traits::length(s)); }
+
+
+ //! <b>Effects</b>: Three-way lexicographical comparison of the first
+ //! min(len, traits::length(s) characters of s and a substring of *this.
+ int compare(size_type pos1, size_type n1, const CharT* s,
+ size_type n2 = npos) const
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ return s_compare(this->priv_addr() + pos1,
+ this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
+ s, s + n2);
+ }
+
+ /// @cond
+ private:
+ static int s_compare(const_pointer f1, const_pointer l1,
+ const_pointer f2, const_pointer l2)
+ {
+ const std::ptrdiff_t n1 = l1 - f1;
+ const std::ptrdiff_t n2 = l2 - f2;
+ const int cmp = Traits::compare(containers_detail::get_pointer(f1),
+ containers_detail::get_pointer(f2),
+ containers_detail::min_value(n1, n2));
+ return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
+ }
+
+ void priv_construct_null(pointer p)
+ { this->construct(p, 0); }
+
+ static CharT priv_null()
+ { return (CharT) 0; }
+
+ // Helper functions used by constructors. It is a severe error for
+ // any of them to be called anywhere except from within constructors.
+ void priv_terminate_string()
+ { this->priv_construct_null(this->priv_addr() + this->priv_size()); }
+
+ template <class InputIter>
+ void priv_range_initialize(InputIter f, InputIter l,
+ std::input_iterator_tag)
+ {
+ this->allocate_initial_block(InternalBufferChars);
+ this->priv_construct_null(this->priv_addr() + this->priv_size());
+ this->append(f, l);
+ }
+
+ template <class ForwardIter>
+ void priv_range_initialize(ForwardIter f, ForwardIter l,
+ std::forward_iterator_tag)
+ {
+ difference_type n = std::distance(f, l);
+ this->allocate_initial_block(containers_detail::max_value<difference_type>(n+1, InternalBufferChars));
+ priv_uninitialized_copy(f, l, this->priv_addr());
+ this->priv_size(n);
+ this->priv_terminate_string();
+ }
+
+ template <class InputIter>
+ void priv_range_initialize(InputIter f, InputIter l)
+ {
+ typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ this->priv_range_initialize(f, l, Category());
+ }
+
+ template <class Integer>
+ void priv_initialize_dispatch(Integer n, Integer x, containers_detail::true_)
+ {
+ this->allocate_initial_block(containers_detail::max_value<difference_type>(n+1, InternalBufferChars));
+ priv_uninitialized_fill_n(this->priv_addr(), n, x);
+ this->priv_size(n);
+ this->priv_terminate_string();
+ }
+
+ template <class InputIter>
+ void priv_initialize_dispatch(InputIter f, InputIter l, containers_detail::false_)
+ { this->priv_range_initialize(f, l); }
+
+ template<class FwdIt, class Count> inline
+ void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
+ {
+ //Save initial position
+ FwdIt init = first;
+
+ BOOST_TRY{
+ //Construct objects
+ for (; count--; ++first){
+ this->construct(first, val);
+ }
+ }
+ BOOST_CATCH(...){
+ //Call destructors
+ for (; init != first; ++init){
+ this->destroy(init);
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template<class InpIt, class FwdIt> inline
+ size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
+ {
+ //Save initial destination position
+ FwdIt dest_init = dest;
+ size_type constructed = 0;
+
+ BOOST_TRY{
+ //Try to build objects
+ for (; first != last; ++dest, ++first, ++constructed){
+ this->construct(dest, *first);
+ }
+ }
+ BOOST_CATCH(...){
+ //Call destructors
+ for (; constructed--; ++dest_init){
+ this->destroy(dest_init);
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ return (constructed);
+ }
+
+ template <class Integer>
+ basic_string& priv_assign_dispatch(Integer n, Integer x, containers_detail::true_)
+ { return this->assign((size_type) n, (CharT) x); }
+
+ template <class InputIter>
+ basic_string& priv_assign_dispatch(InputIter f, InputIter l,
+ containers_detail::false_)
+ {
+ size_type cur = 0;
+ CharT *ptr = containers_detail::get_pointer(this->priv_addr());
+ while (f != l && cur != this->priv_size()) {
+ Traits::assign(*ptr, *f);
+ ++f;
+ ++cur;
+ ++ptr;
+ }
+ if (f == l)
+ this->erase(this->priv_addr() + cur, this->priv_addr() + this->priv_size());
+ else
+ this->append(f, l);
+ return *this;
+ }
+
+ template <class InputIter>
+ void priv_insert(iterator p, InputIter first, InputIter last, std::input_iterator_tag)
+ {
+ for ( ; first != last; ++first, ++p) {
+ p = this->insert(p, *first);
+ }
+ }
+
+ template <class ForwardIter>
+ void priv_insert(iterator position, ForwardIter first,
+ ForwardIter last, std::forward_iterator_tag)
+ {
+ if (first != last) {
+ size_type n = std::distance(first, last);
+ size_type remaining = this->capacity() - this->priv_size();
+ const size_type old_size = this->size();
+ pointer old_start = this->priv_addr();
+ bool enough_capacity = false;
+ std::pair<pointer, bool> allocation_ret;
+ size_type new_cap = 0;
+
+ //Check if we have enough capacity
+ if (remaining >= n){
+ enough_capacity = true;
+ }
+ else {
+ //Otherwise expand current buffer or allocate new storage
+ new_cap = this->next_capacity(n);
+ allocation_ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
+ new_cap, new_cap, old_start);
+
+ //Check forward expansion
+ if(old_start == allocation_ret.first){
+ enough_capacity = true;
+ this->priv_storage(new_cap);
+ }
+ }
+
+ //Reuse same buffer
+ if(enough_capacity){
+ const size_type elems_after =
+ this->priv_size() - (position - this->priv_addr());
+ size_type old_length = this->priv_size();
+ if (elems_after >= n) {
+ pointer pointer_past_last = this->priv_addr() + this->priv_size() + 1;
+ priv_uninitialized_copy(this->priv_addr() + (this->priv_size() - n + 1),
+ pointer_past_last, pointer_past_last);
+
+ this->priv_size(this->priv_size()+n);
+ Traits::move(containers_detail::get_pointer(position + n),
+ containers_detail::get_pointer(position),
+ (elems_after - n) + 1);
+ this->priv_copy(first, last, position);
+ }
+ else {
+ ForwardIter mid = first;
+ std::advance(mid, elems_after + 1);
+
+ priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1);
+ this->priv_size(this->priv_size() + (n - elems_after));
+ priv_uninitialized_copy
+ (position, this->priv_addr() + old_length + 1,
+ this->priv_addr() + this->priv_size());
+ this->priv_size(this->priv_size() + elems_after);
+ this->priv_copy(first, mid, position);
+ }
+ }
+ else{
+ pointer new_start = allocation_ret.first;
+ if(!allocation_ret.second){
+ //Copy data to new buffer
+ size_type new_length = 0;
+ //This can't throw, since characters are POD
+ new_length += priv_uninitialized_copy
+ (this->priv_addr(), position, new_start);
+ new_length += priv_uninitialized_copy
+ (first, last, new_start + new_length);
+ new_length += priv_uninitialized_copy
+ (position, this->priv_addr() + this->priv_size(),
+ new_start + new_length);
+ this->priv_construct_null(new_start + new_length);
+
+ this->deallocate_block();
+ this->is_short(false);
+ this->priv_addr(new_start);
+ this->priv_size(new_length);
+ this->priv_storage(new_cap);
+ }
+ else{
+ //value_type is POD, so backwards expansion is much easier
+ //than with vector<T>
+ value_type *oldbuf = containers_detail::get_pointer(old_start);
+ value_type *newbuf = containers_detail::get_pointer(new_start);
+ value_type *pos = containers_detail::get_pointer(position);
+ size_type before = pos - oldbuf;
+
+ //First move old data
+ Traits::move(newbuf, oldbuf, before);
+ Traits::move(newbuf + before + n, pos, old_size - before);
+ //Now initialize the new data
+ priv_uninitialized_copy(first, last, new_start + before);
+ this->priv_construct_null(new_start + (old_size + n));
+ this->is_short(false);
+ this->priv_addr(new_start);
+ this->priv_size(old_size + n);
+ this->priv_storage(new_cap);
+ }
+ }
+ }
+ }
+
+ template <class Integer>
+ void priv_insert_dispatch(iterator p, Integer n, Integer x,
+ containers_detail::true_)
+ { insert(p, (size_type) n, (CharT) x); }
+
+ template <class InputIter>
+ void priv_insert_dispatch(iterator p, InputIter first, InputIter last,
+ containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ priv_insert(p, first, last, Category());
+ }
+
+ template <class InputIterator>
+ void priv_copy(InputIterator first, InputIterator last, iterator result)
+ {
+ for ( ; first != last; ++first, ++result)
+ Traits::assign(*result, *first);
+ }
+
+ void priv_copy(const CharT* first, const CharT* last, CharT* result)
+ { Traits::copy(result, first, last - first); }
+
+ template <class Integer>
+ basic_string& priv_replace_dispatch(iterator first, iterator last,
+ Integer n, Integer x,
+ containers_detail::true_)
+ { return this->replace(first, last, (size_type) n, (CharT) x); }
+
+ template <class InputIter>
+ basic_string& priv_replace_dispatch(iterator first, iterator last,
+ InputIter f, InputIter l,
+ containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ return this->priv_replace(first, last, f, l, Category());
+ }
+
+
+ template <class InputIter>
+ basic_string& priv_replace(iterator first, iterator last,
+ InputIter f, InputIter l, std::input_iterator_tag)
+ {
+ for ( ; first != last && f != l; ++first, ++f)
+ Traits::assign(*first, *f);
+
+ if (f == l)
+ this->erase(first, last);
+ else
+ this->insert(last, f, l);
+ return *this;
+ }
+
+ template <class ForwardIter>
+ basic_string& priv_replace(iterator first, iterator last,
+ ForwardIter f, ForwardIter l,
+ std::forward_iterator_tag)
+ {
+ difference_type n = std::distance(f, l);
+ const difference_type len = last - first;
+ if (len >= n) {
+ this->priv_copy(f, l, first);
+ this->erase(first + n, last);
+ }
+ else {
+ ForwardIter m = f;
+ std::advance(m, len);
+ this->priv_copy(f, m, first);
+ this->insert(last, m, l);
+ }
+ return *this;
+ }
+ /// @endcond
+};
+
+/// @cond
+
+template <class CharT, class Traits, class A>
+const typename basic_string<CharT,Traits,A>::size_type
+basic_string<CharT,Traits,A>::npos
+ = (typename basic_string<CharT,Traits,A>::size_type) -1;
+
+/// @endcond
+
+// ------------------------------------------------------------
+// Non-member functions.
+
+// Operator+
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ str_t result(reserve, x.size() + y.size(), x.alloc());
+ result.append(x);
+ result.append(y);
+ return result;
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+ operator+(
+ BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+ , const basic_string<CharT,Traits,A>& y)
+{
+ mx += y;
+ return boost::interprocess::move(mx);
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+ operator+(const basic_string<CharT,Traits,A>& x,
+ BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+ typedef typename basic_string<CharT,Traits,A>::size_type size_type;
+ return my.replace(size_type(0), size_type(0), x);
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const CharT* s, const basic_string<CharT,Traits,A>& y)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ const std::size_t n = Traits::length(s);
+ str_t result(reserve, n + y.size());
+ result.append(s, s + n);
+ result.append(y);
+ return result;
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(const CharT* s,
+ BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+ typedef typename basic_string<CharT,Traits,A>::size_type size_type;
+ return boost::interprocess::move(my.get().replace(size_type(0), size_type(0), s));
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(CharT c, const basic_string<CharT,Traits,A>& y)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ str_t result(reserve, 1 + y.size());
+ result.push_back(c);
+ result.append(y);
+ return result;
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(CharT c,
+ BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+ typedef typename basic_string<CharT,Traits,A>::size_type size_type;
+ return my.replace(size_type(0), size_type(0), &c, &c + 1);
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ const std::size_t n = Traits::length(s);
+ str_t result(reserve, x.size() + n, x.alloc());
+ result.append(x);
+ result.append(s, s + n);
+ return result;
+}
+
+template <class CharT, class Traits, class A>
+BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+ , const CharT* s)
+{
+ mx += s;
+ return boost::interprocess::move(mx);
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ str_t result(reserve, x.size() + 1, x.alloc());
+ result.append(x);
+ result.push_back(c);
+ return result;
+}
+
+template <class CharT, class Traits, class A>
+BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+( BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+ , const CharT c)
+{
+ mx += c;
+ return boost::interprocess::move(mx);
+}
+
+// Operator== and operator!=
+
+template <class CharT, class Traits, class A>
+inline bool
+operator==(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+{
+ return x.size() == y.size() &&
+ Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator==(const CharT* s, const basic_string<CharT,Traits,A>& y)
+{
+ std::size_t n = Traits::length(s);
+ return n == y.size() && Traits::compare(s, y.data(), n) == 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator==(const basic_string<CharT,Traits,A>& x, const CharT* s)
+{
+ std::size_t n = Traits::length(s);
+ return x.size() == n && Traits::compare(x.data(), s, n) == 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator!=(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+ { return !(x == y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator!=(const CharT* s, const basic_string<CharT,Traits,A>& y)
+ { return !(s == y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator!=(const basic_string<CharT,Traits,A>& x, const CharT* s)
+ { return !(x == s); }
+
+
+// Operator< (and also >, <=, and >=).
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<(const basic_string<CharT,Traits,A>& x, const basic_string<CharT,Traits,A>& y)
+{
+ return x.compare(y) < 0;
+// return basic_string<CharT,Traits,A>
+// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<(const CharT* s, const basic_string<CharT,Traits,A>& y)
+{
+ return y.compare(s) > 0;
+// std::size_t n = Traits::length(s);
+// return basic_string<CharT,Traits,A>
+// ::s_compare(s, s + n, y.begin(), y.end()) < 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<(const basic_string<CharT,Traits,A>& x,
+ const CharT* s)
+{
+ return x.compare(s) < 0;
+// std::size_t n = Traits::length(s);
+// return basic_string<CharT,Traits,A>
+// ::s_compare(x.begin(), x.end(), s, s + n) < 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y) {
+ return y < x;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>(const CharT* s, const basic_string<CharT,Traits,A>& y) {
+ return y < s;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>(const basic_string<CharT,Traits,A>& x, const CharT* s)
+{
+ return s < x;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<=(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+{
+ return !(y < x);
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<=(const CharT* s, const basic_string<CharT,Traits,A>& y)
+ { return !(y < s); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<=(const basic_string<CharT,Traits,A>& x, const CharT* s)
+ { return !(s < x); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>=(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+ { return !(x < y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>=(const CharT* s, const basic_string<CharT,Traits,A>& y)
+ { return !(s < y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>=(const basic_string<CharT,Traits,A>& x, const CharT* s)
+ { return !(x < s); }
+
+// Swap.
+template <class CharT, class Traits, class A>
+inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>& y)
+{ x.swap(y); }
+
+/// @cond
+// I/O.
+namespace containers_detail {
+
+template <class CharT, class Traits>
+inline bool
+string_fill(std::basic_ostream<CharT, Traits>& os,
+ std::basic_streambuf<CharT, Traits>* buf,
+ std::size_t n)
+{
+ CharT f = os.fill();
+ std::size_t i;
+ bool ok = true;
+
+ for (i = 0; i < n; i++)
+ ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
+ return ok;
+}
+
+} //namespace containers_detail {
+/// @endcond
+
+template <class CharT, class Traits, class A>
+std::basic_ostream<CharT, Traits>&
+operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,A>& s)
+{
+ typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
+ bool ok = false;
+
+ if (sentry) {
+ ok = true;
+ std::size_t n = s.size();
+ std::size_t pad_len = 0;
+ const bool left = (os.flags() & std::ios::left) != 0;
+ const std::size_t w = os.width(0);
+ std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
+
+ if (w != 0 && n < w)
+ pad_len = w - n;
+
+ if (!left)
+ ok = containers_detail::string_fill(os, buf, pad_len);
+
+ ok = ok &&
+ buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
+
+ if (left)
+ ok = ok && containers_detail::string_fill(os, buf, pad_len);
+ }
+
+ if (!ok)
+ os.setstate(std::ios_base::failbit);
+
+ return os;
+}
+
+
+template <class CharT, class Traits, class A>
+std::basic_istream<CharT, Traits>&
+operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s)
+{
+ typename std::basic_istream<CharT, Traits>::sentry sentry(is);
+
+ if (sentry) {
+ std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+ const std::ctype<CharT>& ctype = std::use_facet<std::ctype<CharT> >(is.getloc());
+
+ s.clear();
+ std::size_t n = is.width(0);
+ if (n == 0)
+ n = static_cast<std::size_t>(-1);
+ else
+ s.reserve(n);
+
+ while (n-- > 0) {
+ typename Traits::int_type c1 = buf->sbumpc();
+
+ if (Traits::eq_int_type(c1, Traits::eof())) {
+ is.setstate(std::ios_base::eofbit);
+ break;
+ }
+ else {
+ CharT c = Traits::to_char_type(c1);
+
+ if (ctype.is(std::ctype<CharT>::space, c)) {
+ if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof()))
+ is.setstate(std::ios_base::failbit);
+ break;
+ }
+ else
+ s.push_back(c);
+ }
+ }
+
+ // If we have read no characters, then set failbit.
+ if (s.size() == 0)
+ is.setstate(std::ios_base::failbit);
+ }
+ else
+ is.setstate(std::ios_base::failbit);
+
+ return is;
+}
+
+template <class CharT, class Traits, class A>
+std::basic_istream<CharT, Traits>&
+getline(std::istream& is, basic_string<CharT,Traits,A>& s,CharT delim)
+{
+ std::size_t nread = 0;
+ typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
+ if (sentry) {
+ std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+ s.clear();
+
+ int c1;
+ while (nread < s.max_size()) {
+ int c1 = buf->sbumpc();
+ if (Traits::eq_int_type(c1, Traits::eof())) {
+ is.setstate(std::ios_base::eofbit);
+ break;
+ }
+ else {
+ ++nread;
+ CharT c = Traits::to_char_type(c1);
+ if (!Traits::eq(c, delim))
+ s.push_back(c);
+ else
+ break; // Character is extracted but not appended.
+ }
+ }
+ }
+ if (nread == 0 || nread >= s.max_size())
+ is.setstate(std::ios_base::failbit);
+
+ return is;
+}
+
+template <class CharT, class Traits, class A>
+inline std::basic_istream<CharT, Traits>&
+getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s)
+{
+ return getline(is, s, '\n');
+}
+
+template <class Ch, class A>
+inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v)
+{
+ return hash_range(v.begin(), v.end());
+}
+
+}}
+
+/// @cond
+
+namespace boost {
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class C, class T, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::basic_string<C, T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+
+}}
+
+/// @endcond
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_STRING_HPP
Added: trunk/boost/interprocess/containers/container/vector.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/vector.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,1933 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This file comes from SGI's stl_vector.h file. Modified by Ion Gaztanaga.
+// Renaming, isolating and porting to generic algorithms. Pointer typedef
+// set to allocator::pointer to allow placing it in shared memory.
+//
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1996
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_VECTOR_HPP
+#define BOOST_CONTAINERS_CONTAINERS_VECTOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+
+#include <cstddef>
+#include <memory>
+#include <algorithm>
+#include <stdexcept>
+#include <iterator>
+#include <utility>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/interprocess/containers/container/detail/allocation_type.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/iterators.hpp>
+#include <boost/interprocess/containers/container/detail/algorithms.hpp>
+#include <boost/interprocess/containers/container/detail/destroyers.hpp>
+#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/advanced_insert_int.hpp>
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+namespace boost {
+namespace interprocess {
+#else
+namespace boost {
+namespace interprocess_container {
+#endif
+
+/// @cond
+
+namespace containers_detail {
+
+//! Const vector_iterator used to iterate through a vector.
+template <class Pointer>
+class vector_const_iterator
+ : public std::iterator<std::random_access_iterator_tag
+ ,const typename std::iterator_traits<Pointer>::value_type
+ ,typename std::iterator_traits<Pointer>::difference_type
+ ,typename boost::pointer_to_other
+ <Pointer
+ ,const typename std::iterator_traits<Pointer>::value_type
+ >::type
+ ,const typename std::iterator_traits<Pointer>::value_type &>
+{
+ public:
+ typedef const typename std::iterator_traits<Pointer>::value_type value_type;
+ typedef typename std::iterator_traits<Pointer>::difference_type difference_type;
+ typedef typename boost::pointer_to_other<Pointer, value_type>::type pointer;
+ typedef value_type& reference;
+
+ /// @cond
+ protected:
+ Pointer m_ptr;
+
+ public:
+ Pointer get_ptr() const { return m_ptr; }
+ explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){}
+ /// @endcond
+
+ public:
+
+ //Constructors
+ vector_const_iterator() : m_ptr(0){}
+
+ //Pointer like operators
+ reference operator*() const
+ { return *m_ptr; }
+
+ const value_type * operator->() const
+ { return containers_detail::get_pointer(m_ptr); }
+
+ reference operator[](difference_type off) const
+ { return m_ptr[off]; }
+
+ //Increment / Decrement
+ vector_const_iterator& operator++()
+ { ++m_ptr; return *this; }
+
+ vector_const_iterator operator++(int)
+ { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); }
+
+ vector_const_iterator& operator--()
+ { --m_ptr; return *this; }
+
+ vector_const_iterator operator--(int)
+ { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); }
+
+ //Arithmetic
+ vector_const_iterator& operator+=(difference_type off)
+ { m_ptr += off; return *this; }
+
+ vector_const_iterator operator+(difference_type off) const
+ { return vector_const_iterator(m_ptr+off); }
+
+ friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right)
+ { return vector_const_iterator(off + right.m_ptr); }
+
+ vector_const_iterator& operator-=(difference_type off)
+ { m_ptr -= off; return *this; }
+
+ vector_const_iterator operator-(difference_type off) const
+ { return vector_const_iterator(m_ptr-off); }
+
+ difference_type operator-(const vector_const_iterator& right) const
+ { return m_ptr - right.m_ptr; }
+
+ //Comparison operators
+ bool operator== (const vector_const_iterator& r) const
+ { return m_ptr == r.m_ptr; }
+
+ bool operator!= (const vector_const_iterator& r) const
+ { return m_ptr != r.m_ptr; }
+
+ bool operator< (const vector_const_iterator& r) const
+ { return m_ptr < r.m_ptr; }
+
+ bool operator<= (const vector_const_iterator& r) const
+ { return m_ptr <= r.m_ptr; }
+
+ bool operator> (const vector_const_iterator& r) const
+ { return m_ptr > r.m_ptr; }
+
+ bool operator>= (const vector_const_iterator& r) const
+ { return m_ptr >= r.m_ptr; }
+};
+
+//! Iterator used to iterate through a vector
+template <class Pointer>
+class vector_iterator
+ : public vector_const_iterator<Pointer>
+{
+ public:
+ explicit vector_iterator(Pointer ptr)
+ : vector_const_iterator<Pointer>(ptr)
+ {}
+
+ public:
+ typedef typename std::iterator_traits<Pointer>::value_type value_type;
+ typedef typename vector_const_iterator<Pointer>::difference_type difference_type;
+ typedef Pointer pointer;
+ typedef value_type& reference;
+
+ //Constructors
+ vector_iterator()
+ {}
+
+ //Pointer like operators
+ reference operator*() const
+ { return *this->m_ptr; }
+
+ value_type* operator->() const
+ { return containers_detail::get_pointer(this->m_ptr); }
+
+ reference operator[](difference_type off) const
+ { return this->m_ptr[off]; }
+
+ //Increment / Decrement
+ vector_iterator& operator++()
+ { ++this->m_ptr; return *this; }
+
+ vector_iterator operator++(int)
+ { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); }
+
+ vector_iterator& operator--()
+ { --this->m_ptr; return *this; }
+
+ vector_iterator operator--(int)
+ { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); }
+
+ // Arithmetic
+ vector_iterator& operator+=(difference_type off)
+ { this->m_ptr += off; return *this; }
+
+ vector_iterator operator+(difference_type off) const
+ { return vector_iterator(this->m_ptr+off); }
+
+ friend vector_iterator operator+(difference_type off, const vector_iterator& right)
+ { return vector_iterator(off + right.m_ptr); }
+
+ vector_iterator& operator-=(difference_type off)
+ { this->m_ptr -= off; return *this; }
+
+ vector_iterator operator-(difference_type off) const
+ { return vector_iterator(this->m_ptr-off); }
+
+ difference_type operator-(const vector_const_iterator<Pointer>& right) const
+ { return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; }
+};
+
+template <class T, class A>
+struct vector_value_traits
+{
+ typedef T value_type;
+ typedef A allocator_type;
+ static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr_after_move =
+ boost::interprocess::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_copy = has_trivial_copy<value_type>::value;
+ static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
+ static const bool trivial_assign = has_trivial_assign<value_type>::value;
+ static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
+
+ //This is the anti-exception array destructor
+ //to deallocate values already constructed
+ typedef typename containers_detail::if_c
+ <trivial_dctr
+ ,containers_detail::null_scoped_destructor_n<allocator_type>
+ ,containers_detail::scoped_destructor_n<allocator_type>
+ >::type OldArrayDestructor;
+ //This is the anti-exception array destructor
+ //to destroy objects created with copy construction
+ typedef typename containers_detail::if_c
+ <nothrow_copy
+ ,containers_detail::null_scoped_destructor_n<allocator_type>
+ ,containers_detail::scoped_destructor_n<allocator_type>
+ >::type UCopiedArrayDestructor;
+ //This is the anti-exception array deallocator
+ typedef typename containers_detail::if_c
+ <nothrow_copy
+ ,containers_detail::null_scoped_array_deallocator<allocator_type>
+ ,containers_detail::scoped_array_deallocator<allocator_type>
+ >::type UCopiedArrayDeallocator;
+};
+
+//!This struct deallocates and allocated memory
+template <class A>
+struct vector_alloc_holder
+{
+ typedef typename A::pointer pointer;
+ typedef typename A::size_type size_type;
+ typedef typename A::value_type value_type;
+ typedef vector_value_traits<value_type, A> value_traits;
+
+ //Constructor, does not throw
+ vector_alloc_holder(const A &a)
+ : members_(a)
+ {}
+
+ //Constructor, does not throw
+ vector_alloc_holder(const vector_alloc_holder<A> &h)
+ : members_(h.alloc())
+ {}
+
+ //Destructor
+ ~vector_alloc_holder()
+ {
+ this->prot_destroy_all();
+ this->prot_deallocate();
+ }
+
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::interprocess_container::containers_detail::version<A>::value> alloc_version;
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0)
+ {
+ return allocation_command(command, limit_size, preferred_size,
+ received_size, reuse, alloc_version());
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ const pointer &reuse,
+ allocator_v1)
+ {
+ (void)limit_size;
+ (void)reuse;
+ if(!(command & allocate_new))
+ return std::pair<pointer, bool>(pointer(0), 0);
+ received_size = preferred_size;
+ return std::make_pair(this->alloc().allocate(received_size), false);
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ const pointer &reuse,
+ allocator_v2)
+ {
+ return this->alloc().allocation_command
+ (command, limit_size, preferred_size, received_size, reuse);
+ }
+
+ size_type next_capacity(size_type additional_objects) const
+ { return get_next_capacity(this->alloc().max_size(), this->members_.m_capacity, additional_objects); }
+
+ struct members_holder
+ : public A
+ {
+ private:
+ members_holder(const members_holder&);
+
+ public:
+ members_holder(const A &alloc)
+ : A(alloc), m_start(0), m_size(0), m_capacity(0)
+ {}
+
+ pointer m_start;
+ size_type m_size;
+ size_type m_capacity;
+ } members_;
+
+ protected:
+ void prot_deallocate()
+ {
+ if(!this->members_.m_capacity) return;
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ this->members_.m_start = 0;
+ this->members_.m_size = 0;
+ this->members_.m_capacity = 0;
+ }
+
+ void destroy(value_type* p)
+ {
+ if(!value_traits::trivial_dctr)
+ containers_detail::get_pointer(p)->~value_type();
+ }
+
+ void destroy_n(value_type* p, size_type n)
+ {
+ if(!value_traits::trivial_dctr)
+ for(; n--; ++p) p->~value_type();
+ }
+
+ void prot_destroy_all()
+ {
+ this->destroy_n(containers_detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->members_.m_size = 0;
+ }
+
+ A &alloc()
+ { return members_; }
+
+ const A &alloc() const
+ { return members_; }
+};
+
+} //namespace containers_detail {
+/// @endcond
+
+//! \class ::boost::interprocess::vector boost/interprocess/containers/container/vector.hpp <boost/interprocess/containers/vector.hpp>
+//! A vector is a sequence that supports random access to elements, constant
+//! time insertion and removal of elements at the end, and linear time insertion
+//! and removal of elements at the beginning or in the middle. The number of
+//! elements in a vector may vary dynamically; memory management is automatic.
+//! boost::interprocess_container::vector is similar to std::vector but it's compatible
+//! with shared memory and memory mapped files.
+template <class T, class A>
+class vector : private containers_detail::vector_alloc_holder<A>
+{
+ /// @cond
+ typedef vector<T, A> self_t;
+ typedef containers_detail::vector_alloc_holder<A> base_t;
+ /// @endcond
+ public:
+ //! The type of object, T, stored in the vector
+ typedef T value_type;
+ //! Pointer to T
+ typedef typename A::pointer pointer;
+ //! Const pointer to T
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to T
+ typedef typename A::reference reference;
+ //! Const reference to T
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! The allocator type
+ typedef A allocator_type;
+ //! The random access iterator
+ typedef containers_detail::vector_iterator<pointer> iterator;
+ //! The random access const_iterator
+ typedef containers_detail::vector_const_iterator<pointer> const_iterator;
+
+ //! Iterator used to iterate backwards through a vector.
+ typedef std::reverse_iterator<iterator>
+ reverse_iterator;
+ //! Const iterator used to iterate backwards through a vector.
+ typedef std::reverse_iterator<const_iterator>
+ const_reverse_iterator;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+
+ /// @cond
+ private:
+ typedef containers_detail::advanced_insert_aux_int<T, T*> advanced_insert_aux_int_t;
+ typedef containers_detail::vector_value_traits<value_type, A> value_traits;
+
+ typedef typename base_t::allocator_v1 allocator_v1;
+ typedef typename base_t::allocator_v2 allocator_v2;
+ typedef typename base_t::alloc_version alloc_version;
+
+ typedef constant_iterator<T, difference_type> cvalue_iterator;
+ typedef repeat_iterator<T, difference_type> repeat_it;
+ typedef boost::interprocess::move_iterator<repeat_it> repeat_move_it;
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(vector)
+
+ //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit vector(const A& a = A())
+ : base_t(a)
+ {}
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts n default contructed values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ vector(size_type n)
+ : base_t(allocator_type())
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ vector(size_type n, const T& value, const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->insert(this->cend(), n, value); }
+
+ //! <b>Effects</b>: Copy constructs a vector.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ vector(const vector<T, A>& x)
+ : base_t((base_t&)x)
+ { *this = x; }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ vector(BOOST_INTERPROCESS_RV_REF(vector) mx)
+ : base_t(boost::interprocess::move(mx))
+ { this->swap(mx); }
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the vector.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InIt>
+ vector(InIt first, InIt last, const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->assign(first, last); }
+
+ //! <b>Effects</b>: Destroys the vector. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~vector()
+ {} //vector_alloc_holder clears the data
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return const_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return iterator(this->members_.m_start + this->members_.m_size); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin()const
+ { return this->crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(this->begin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->members_.m_start + this->members_.m_size); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin()const
+ { return const_reverse_iterator(this->end());}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->begin()); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return *this->members_.m_start; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->members_.m_start; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back()
+ { return this->members_.m_start[this->members_.m_size - 1]; }
+
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back() const
+ { return this->members_.m_start[this->members_.m_size - 1]; }
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ pointer data()
+ { return this->members_.m_start; }
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_pointer data() const
+ { return this->members_.m_start; }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->members_.m_size; }
+
+ //! <b>Effects</b>: Returns the largest possible size of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return this->alloc().max_size(); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return this->members_.m_capacity; }
+
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->members_.m_size; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n)
+ { return this->members_.m_start[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n) const
+ { return this->members_.m_start[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n)
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n) const
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return this->alloc(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->alloc(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ void reserve(size_type new_cap)
+ {
+ if (this->capacity() < new_cap){
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ bool same_buffer_start;
+ size_type real_cap = 0;
+ std::pair<pointer, bool> ret =
+ this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ new_cap, new_cap, real_cap, this->members_.m_start);
+
+ //Check for forward expansion
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->members_.m_capacity = real_cap;
+ }
+
+ //If there is no forward expansion, move objects
+ else{
+ //We will reuse insert code, so create a dummy input iterator
+ T *dummy_it(containers_detail::get_pointer(this->members_.m_start));
+ containers_detail::advanced_insert_aux_proxy<T, boost::interprocess::move_iterator<T*>, T*>
+ proxy(boost::interprocess::make_move_iterator(dummy_it), boost::interprocess::make_move_iterator(dummy_it));
+ //Backwards (and possibly forward) expansion
+ if(ret.second){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
+ this->priv_range_insert_expand_backwards
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(this->members_.m_start)
+ , 0
+ , proxy);
+ }
+ //New buffer
+ else{
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(this->members_.m_start)
+ , 0
+ , proxy);
+ }
+ }
+ }
+ }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ vector& operator=(const vector& x)
+ {
+ if (&x != this){
+ this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ vector& operator=(BOOST_INTERPROCESS_RV_REF(vector) x)
+ {
+ if (&x != this){
+ this->swap(x);
+ x.clear();
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const value_type& val)
+ { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InIt>
+ void assign(InIt first, InIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(const T& x)
+ {
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size))value_type(x);
+ ++this->members_.m_size;
+ }
+ else{
+ this->insert(this->cend(), x);
+ }
+ }
+
+ //! <b>Effects</b>: Constructs a new element in the end of the vector
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(BOOST_INTERPROCESS_RV_REF(T) x)
+ {
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)containers_detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(boost::interprocess::move(x));
+ ++this->members_.m_size;
+ }
+ else{
+ this->insert(this->cend(), boost::interprocess::move(x));
+ }
+ }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template<class ...Args>
+ void emplace_back(Args &&...args)
+ {
+ T* back_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)(back_pos))value_type(boost::interprocess::forward<Args>(args)...);
+ ++this->members_.m_size;
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, T*, Args...> proxy
+ (boost::interprocess::forward<Args>(args)...);
+ priv_range_insert(back_pos, 1, proxy);
+ }
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template<class ...Args>
+ iterator emplace(const_iterator position, Args && ...args)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ containers_detail::advanced_insert_aux_emplace<T, T*, Args...> proxy
+ (boost::interprocess::forward<Args>(args)...);
+ priv_range_insert(position.get_ptr(), 1, proxy);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ #else
+
+ void emplace_back()
+ {
+ T* back_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)(back_pos))value_type();
+ ++this->members_.m_size;
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<value_type, T*> proxy;
+ priv_range_insert(back_pos, 1, proxy);
+ }
+ }
+
+ iterator emplace(const_iterator position)
+ {
+ size_type pos_n = position - cbegin();
+ containers_detail::advanced_insert_aux_emplace<value_type, T*> proxy;
+ priv_range_insert(containers_detail::get_pointer(position.get_ptr()), 1, proxy);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ T* back_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size; \
+ if (this->members_.m_size < this->members_.m_capacity){ \
+ new((void*)(back_pos))value_type \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ ++this->members_.m_size; \
+ } \
+ else{ \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_range_insert(back_pos, 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ size_type pos_n = pos - cbegin(); \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_range_insert(containers_detail::get_pointer(pos.get_ptr()), 1, proxy); \
+ return iterator(this->members_.m_start + pos_n); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(vector& x)
+ {
+ allocator_type &this_al = this->alloc(), &other_al = x.alloc();
+ //Just swap internals
+ containers_detail::do_swap(this->members_.m_start, x.members_.m_start);
+ containers_detail::do_swap(this->members_.m_size, x.members_.m_size);
+ containers_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity);
+
+ if (this_al != other_al){
+ containers_detail::do_swap(this_al, other_al);
+ }
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before position.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, const T& x)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position, (size_type)1, x);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before position with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(T) x)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position
+ ,repeat_move_it(repeat_it(x, 1))
+ ,repeat_move_it(repeat_it()));
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last).
+ template <class InIt>
+ void insert(const_iterator pos, InIt first, InIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InIt, std::size_t>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(pos, first, last, Result());
+ }
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert n copies of x before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void insert(const_iterator p, size_type n, const T& x)
+ { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Removes the last element from the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ void pop_back()
+ {
+ //Destroy last element
+ --this->members_.m_size;
+ this->destroy(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ }
+
+ //! <b>Effects</b>: Erases the element at position pos.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the elements between pos and the
+ //! last element. Constant if pos is the first or the last element.
+ iterator erase(const_iterator position)
+ {
+ T *pos = containers_detail::get_pointer(position.get_ptr());
+ T *beg = containers_detail::get_pointer(this->members_.m_start);
+ boost::interprocess::move(pos + 1, beg + this->members_.m_size, pos);
+ --this->members_.m_size;
+ //Destroy last element
+ base_t::destroy(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ return iterator(position.get_ptr());
+ }
+
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last.
+ iterator erase(const_iterator first, const_iterator last)
+ {
+ if (first != last){ // worth doing, copy down over hole
+ T* end_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ T* ptr = containers_detail::get_pointer(boost::interprocess::move
+ (containers_detail::get_pointer(last.get_ptr())
+ ,end_pos
+ ,containers_detail::get_pointer(first.get_ptr())
+ ));
+ size_type destroyed = (end_pos - ptr);
+ this->destroy_n(ptr, destroyed);
+ this->members_.m_size -= destroyed;
+ }
+ return iterator(first.get_ptr());
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ pointer finish = this->members_.m_start + this->members_.m_size;
+ if (new_size < size()){
+ //Destroy last elements
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+ }
+ else{
+ //Insert new elements at the end
+ this->insert(const_iterator(finish), new_size - this->size(), x);
+ }
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ if (new_size < this->size()){
+ //Destroy last elements
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+ }
+ else{
+ size_type n = new_size - this->size();
+ this->reserve(new_size);
+ containers_detail::default_construct_aux_proxy<T, T*, size_type> proxy(n);
+ priv_range_insert(this->cend().get_ptr(), n, proxy);
+ }
+ }
+
+ //! <b>Effects</b>: Erases all the elements of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the vector.
+ void clear()
+ { this->prot_destroy_all(); }
+
+ /// @cond
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { priv_shrink_to_fit(alloc_version()); }
+
+ private:
+ void priv_shrink_to_fit(allocator_v1)
+ {
+ if(this->members_.m_capacity){
+ if(!size()){
+ this->prot_deallocate();
+ }
+ else{
+ //This would not work with stateful allocators
+ vector<T, A>(*this).swap(*this);
+ }
+ }
+ }
+
+ void priv_shrink_to_fit(allocator_v2)
+ {
+ if(this->members_.m_capacity){
+ if(!size()){
+ this->prot_deallocate();
+ }
+ else{
+ size_type received_size;
+ if(this->alloc().allocation_command
+ ( shrink_in_place | nothrow_allocation
+ , this->capacity(), this->size()
+ , received_size, this->members_.m_start).first){
+ this->members_.m_capacity = received_size;
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_shrink;
+ #endif
+ }
+ }
+ }
+ }
+
+ template <class FwdIt>
+ void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ if(first != last){
+ const size_type n = std::distance(first, last);
+ containers_detail::advanced_insert_aux_proxy<T, FwdIt, T*> proxy(first, last);
+ priv_range_insert(pos, n, proxy);
+ }
+ }
+
+ void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //Check if we have enough memory or try to expand current memory
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ bool same_buffer_start;
+ std::pair<pointer, bool> ret;
+ size_type real_cap = this->members_.m_capacity;
+
+ //Check if we already have room
+ if (n <= remaining){
+ same_buffer_start = true;
+ }
+ else{
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ size_type new_cap = this->next_capacity(n);
+ ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
+
+ //Check for forward expansion
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ this->members_.m_capacity = real_cap;
+ }
+ }
+
+ //If we had room or we have expanded forward
+ if (same_buffer_start){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->priv_range_insert_expand_forward
+ (containers_detail::get_pointer(pos), n, interf);
+ }
+ //Backwards (and possibly forward) expansion
+ else if(ret.second){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
+ this->priv_range_insert_expand_backwards
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(pos)
+ , n
+ , interf);
+ }
+ //New buffer
+ else{
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(pos)
+ , n
+ , interf);
+ }
+ }
+
+ void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //There is enough memory
+ T* old_finish = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ const size_type elems_after = old_finish - pos;
+
+ if (elems_after > n){
+ //New elements can be just copied.
+ //Move to uninitialized memory last objects
+ boost::interprocess::uninitialized_move(old_finish - n, old_finish, old_finish);
+ this->members_.m_size += n;
+ //Copy previous to last objects to the initialized end
+ boost::interprocess::move_backward(pos, old_finish - n, old_finish);
+ //Insert new objects in the pos
+ interf.copy_all_to(pos);
+ }
+ else {
+ //The new elements don't fit in the [pos, end()) range. Copy
+ //to the beginning of the unallocated zone the last new elements.
+ interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
+ this->members_.m_size += n - elems_after;
+ //Copy old [pos, end()) elements to the uninitialized memory
+ boost::interprocess::uninitialized_move
+ ( pos, old_finish, containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ this->members_.m_size += elems_after;
+ //Copy first new elements in pos
+ interf.copy_all_to(pos);
+ }
+ }
+
+ void priv_range_insert_new_allocation
+ (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ {
+ T* new_finish = new_start;
+ T *old_finish;
+ //Anti-exception rollbacks
+ typename value_traits::UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
+ typename value_traits::UCopiedArrayDestructor constructed_values_destroyer(new_start, 0u);
+
+ //Initialize with [begin(), pos) old buffer
+ //the start of the new buffer
+ new_finish = boost::interprocess::uninitialized_move
+ (containers_detail::get_pointer(this->members_.m_start), pos, old_finish = new_finish);
+ constructed_values_destroyer.increment_size(new_finish - old_finish);
+ //Initialize new objects, starting from previous point
+ interf.uninitialized_copy_all_to(old_finish = new_finish);
+ new_finish += n;
+ constructed_values_destroyer.increment_size(new_finish - old_finish);
+ //Initialize from the rest of the old buffer,
+ //starting from previous point
+ new_finish = boost::interprocess::uninitialized_move
+ ( pos, containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size, new_finish);
+ //All construction successful, disable rollbacks
+ constructed_values_destroyer.release();
+ scoped_alloc.release();
+ //Destroy and deallocate old elements
+ //If there is allocated memory, destroy and deallocate
+ if(this->members_.m_start != 0){
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(containers_detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ }
+ this->members_.m_start = new_start;
+ this->members_.m_size = new_finish - new_start;
+ this->members_.m_capacity = new_cap;
+ }
+
+ void priv_range_insert_expand_backwards
+ (T* new_start, size_type new_capacity,
+ T* pos, const size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //Backup old data
+ T* old_start = containers_detail::get_pointer(this->members_.m_start);
+ T* old_finish = old_start + this->members_.m_size;
+ size_type old_size = this->members_.m_size;
+
+ //We can have 8 possibilities:
+ const size_type elemsbefore = (size_type)(pos - old_start);
+ const size_type s_before = (size_type)(old_start - new_start);
+
+ //Update the vector buffer information to a safe state
+ this->members_.m_start = new_start;
+ this->members_.m_capacity = new_capacity;
+ this->members_.m_size = 0;
+
+ //If anything goes wrong, this object will destroy
+ //all the old objects to fulfill previous vector state
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
+ //Check if s_before is big enough to hold the beginning of old data + new data
+ if(difference_type(s_before) >= difference_type(elemsbefore + n)){
+ //Copy first old values before pos, after that the new objects
+ boost::interprocess::uninitialized_move(old_start, pos, new_start);
+ this->members_.m_size = elemsbefore;
+ interf.uninitialized_copy_all_to(new_start + elemsbefore);
+ this->members_.m_size += n;
+ //Check if s_before is so big that even copying the old data + new data
+ //there is a gap between the new data and the old data
+ if(s_before >= (old_size + n)){
+ //Old situation:
+ // _________________________________________________________
+ //| raw_mem | old_begin | old_end |
+ //| __________________________________|___________|_________|
+ //
+ //New situation:
+ // _________________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|__________|_________|________________________|
+ //
+ //Now initialize the rest of memory with the last old values
+ boost::interprocess::uninitialized_move
+ (pos, old_finish, new_start + elemsbefore + n);
+ //All new elements correctly constructed, avoid new element destruction
+ this->members_.m_size = old_size + n;
+ //Old values destroyed automatically with "old_values_destroyer"
+ //when "old_values_destroyer" goes out of scope unless the have trivial
+ //destructor after move.
+ if(value_traits::trivial_dctr_after_move)
+ old_values_destroyer.release();
+ }
+ //s_before is so big that divides old_end
+ else{
+ //Old situation:
+ // __________________________________________________
+ //| raw_mem | old_begin | old_end |
+ //| ___________________________|___________|_________|
+ //
+ //New situation:
+ // __________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|__________|_________|_________________|
+ //
+ //Now initialize the rest of memory with the last old values
+ //All new elements correctly constructed, avoid new element destruction
+ size_type raw_gap = s_before - (elemsbefore + n);
+ //Now initialize the rest of s_before memory with the
+ //first of elements after new values
+ boost::interprocess::uninitialized_move(pos, pos + raw_gap, new_start + elemsbefore + n);
+ //Update size since we have a contiguous buffer
+ this->members_.m_size = old_size + s_before;
+ //All new elements correctly constructed, avoid old element destruction
+ old_values_destroyer.release();
+ //Now copy remaining last objects in the old buffer begin
+ T *to_destroy = boost::interprocess::move(pos + raw_gap, old_finish, old_start);
+ //Now destroy redundant elements except if they were moved and
+ //they have trivial destructor after move
+ size_type n_destroy = old_finish - to_destroy;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(to_destroy, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
+ }
+ else{
+ //Check if we have to do the insertion in two phases
+ //since maybe s_before is not big enough and
+ //the buffer was expanded both sides
+ //
+ //Old situation:
+ // _________________________________________________
+ //| raw_mem | old_begin + old_end | raw_mem |
+ //|_________|_____________________|_________________|
+ //
+ //New situation with do_after:
+ // _________________________________________________
+ //| old_begin + new + old_end | raw_mem |
+ //|___________________________________|_____________|
+ //
+ //New without do_after:
+ // _________________________________________________
+ //| old_begin + new + old_end | raw_mem |
+ //|____________________________|____________________|
+ //
+ bool do_after = n > s_before;
+
+ //Now we can have two situations: the raw_mem of the
+ //beginning divides the old_begin, or the new elements:
+ if (s_before <= elemsbefore) {
+ //The raw memory divides the old_begin group:
+ //
+ //If we need two phase construction (do_after)
+ //new group is divided in new = new_beg + new_end groups
+ //In this phase only new_beg will be inserted
+ //
+ //Old situation:
+ // _________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|_________|___________|_________|_________________|
+ //
+ //New situation with do_after(1):
+ //This is not definitive situation, the second phase
+ //will include
+ // _________________________________________________
+ //| old_begin | new_beg | old_end | raw_mem |
+ //|___________|_________|_________|_________________|
+ //
+ //New situation without do_after:
+ // _________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|_____|_________|_____________________|
+ //
+ //Copy the first part of old_begin to raw_mem
+ T *start_n = old_start + difference_type(s_before);
+ boost::interprocess::uninitialized_move(old_start, start_n, new_start);
+ //The buffer is all constructed until old_end,
+ //release destroyer and update size
+ old_values_destroyer.release();
+ this->members_.m_size = old_size + s_before;
+ //Now copy the second part of old_begin overwriting himself
+ T* next = boost::interprocess::move(start_n, pos, old_start);
+ if(do_after){
+ //Now copy the new_beg elements
+ interf.copy_some_and_update(next, s_before, true);
+ }
+ else{
+ //Now copy the all the new elements
+ interf.copy_all_to(next);
+ T* move_start = next + n;
+ //Now displace old_end elements
+ T* move_end = boost::interprocess::move(pos, old_finish, move_start);
+ //Destroy remaining moved elements from old_end except if
+ //they have trivial destructor after being moved
+ difference_type n_destroy = s_before - n;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(move_end, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
+ }
+ else {
+ //If we have to expand both sides,
+ //we will play if the first new values so
+ //calculate the upper bound of new values
+
+ //The raw memory divides the new elements
+ //
+ //If we need two phase construction (do_after)
+ //new group is divided in new = new_beg + new_end groups
+ //In this phase only new_beg will be inserted
+ //
+ //Old situation:
+ // _______________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|_______________|___________|_________|_________________|
+ //
+ //New situation with do_after():
+ // ____________________________________________________
+ //| old_begin | new_beg | old_end | raw_mem |
+ //|___________|_______________|_________|______________|
+ //
+ //New situation without do_after:
+ // ______________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|_____|_________|__________________________|
+ //
+ //First copy whole old_begin and part of new to raw_mem
+ boost::interprocess::uninitialized_move(old_start, pos, new_start);
+ this->members_.m_size = elemsbefore;
+
+ const size_type mid_n = difference_type(s_before) - elemsbefore;
+ interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
+ this->members_.m_size = old_size + s_before;
+ //The buffer is all constructed until old_end,
+ //release destroyer and update size
+ old_values_destroyer.release();
+
+ if(do_after){
+ //Copy new_beg part
+ interf.copy_some_and_update(old_start, s_before - mid_n, true);
+ }
+ else{
+ //Copy all new elements
+ interf.copy_all_to(old_start);
+ T* move_start = old_start + (n-mid_n);
+ //Displace old_end
+ T* move_end = boost::interprocess::move(pos, old_finish, move_start);
+ //Destroy remaining moved elements from old_end except if they
+ //have trivial destructor after being moved
+ difference_type n_destroy = s_before - n;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(move_end, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
+ }
+
+ //This is only executed if two phase construction is needed
+ //This can be executed without exception handling since we
+ //have to just copy and append in raw memory and
+ //old_values_destroyer has been released in phase 1.
+ if(do_after){
+ //The raw memory divides the new elements
+ //
+ //Old situation:
+ // ______________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|______________|___________|____________|______________|
+ //
+ //New situation with do_after(1):
+ // _______________________________________________________
+ //| old_begin + new_beg | new_end |old_end | raw_mem |
+ //|__________________________|_________|________|_________|
+ //
+ //New situation with do_after(2):
+ // ______________________________________________________
+ //| old_begin + new | old_end |raw |
+ //|_______________________________________|_________|____|
+ //
+ const size_type n_after = n - s_before;
+ const difference_type elemsafter = old_size - elemsbefore;
+
+ //We can have two situations:
+ if (elemsafter > difference_type(n_after)){
+ //The raw_mem from end will divide displaced old_end
+ //
+ //Old situation:
+ // ______________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|______________|___________|____________|______________|
+ //
+ //New situation with do_after(1):
+ // _______________________________________________________
+ //| old_begin + new_beg | new_end |old_end | raw_mem |
+ //|__________________________|_________|________|_________|
+ //
+ //First copy the part of old_end raw_mem
+ T* finish_n = old_finish - difference_type(n_after);
+ boost::interprocess::uninitialized_move(finish_n, old_finish, old_finish);
+ this->members_.m_size += n_after;
+ //Displace the rest of old_end to the new position
+ boost::interprocess::move_backward(pos, finish_n, old_finish);
+ //Now overwrite with new_end
+ //The new_end part is [first + (n - n_after), last)
+ interf.copy_all_to(pos);
+ }
+ else {
+ //The raw_mem from end will divide new_end part
+ //
+ //Old situation:
+ // _____________________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|______________|___________|____________|_____________________|
+ //
+ //New situation with do_after(2):
+ // _____________________________________________________________
+ //| old_begin + new_beg | new_end |old_end | raw_mem |
+ //|__________________________|_______________|________|_________|
+ //
+ size_type mid_last_dist = n_after - elemsafter;
+ //First initialize data in raw memory
+ //The new_end part is [first + (n - n_after), last)
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_size += mid_last_dist;
+ boost::interprocess::uninitialized_move(pos, old_finish, old_finish + mid_last_dist);
+ this->members_.m_size += n_after - mid_last_dist;
+ //Now copy the part of new_end over constructed elements
+ interf.copy_all_to(pos);
+ }
+ }
+ }
+ }
+
+ template <class InIt>
+ void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag)
+ {
+ for(;first != last; ++first){
+ this->insert(pos, boost::interprocess::move(value_type(*first)));
+ }
+ }
+
+ template <class InIt>
+ void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag)
+ {
+ //Overwrite all elements we can from [first, last)
+ iterator cur = begin();
+ for ( ; first != last && cur != end(); ++cur, ++first){
+ *cur = *first;
+ }
+
+ if (first == last){
+ //There are no more elements in the sequence, erase remaining
+ this->erase(cur, cend());
+ }
+ else{
+ //There are more elements in the range, insert the remaining ones
+ this->insert(this->cend(), first, last);
+ }
+ }
+
+ template <class FwdIt>
+ void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type n = std::distance(first, last);
+ //Check if we have enough memory or try to expand current memory
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ bool same_buffer_start;
+ std::pair<pointer, bool> ret;
+ size_type real_cap = this->members_.m_capacity;
+
+ if (n <= remaining){
+ same_buffer_start = true;
+ }
+ else{
+ //There is not enough memory, allocate a new buffer
+ size_type new_cap = this->next_capacity(n);
+ ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->size() + n, new_cap, real_cap, this->members_.m_start);
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ this->members_.m_capacity = real_cap;
+ }
+ }
+
+ if(same_buffer_start){
+ T *start = containers_detail::get_pointer(this->members_.m_start);
+ if (this->size() >= n){
+ //There is memory, but there are more old elements than new ones
+ //Overwrite old elements with new ones
+ // iG std::copy(first, last, start);
+ std::copy(first, last, start);
+ //Destroy remaining old elements
+ this->destroy_n(start + n, this->members_.m_size - n);
+ this->members_.m_size = n;
+ }
+ else{
+ //There is memory, but there are less old elements than new ones
+ //First overwrite some old elements with new ones
+ FwdIt mid = first;
+ std::advance(mid, this->size());
+ // iG T *end = std::copy(first, mid, start);
+ T *end = std::copy(first, mid, start);
+ //Initialize the remaining new elements in the uninitialized memory
+ // iG std::uninitialized_copy(mid, last, end);
+ boost::interprocess::uninitialized_copy_or_move(mid, last, end);
+ this->members_.m_size = n;
+ }
+ }
+ else if(!ret.second){
+ typename value_traits::UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
+ // iG std::uninitialized_copy(first, last, containers_detail::get_pointer(ret.first));
+ boost::interprocess::uninitialized_copy_or_move(first, last, containers_detail::get_pointer(ret.first));
+ scoped_alloc.release();
+ //Destroy and deallocate old buffer
+ if(this->members_.m_start != 0){
+ this->destroy_n(containers_detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ }
+ this->members_.m_start = ret.first;
+ this->members_.m_size = n;
+ this->members_.m_capacity = real_cap;
+ }
+ else{
+ //Backwards expansion
+ //If anything goes wrong, this object will destroy old objects
+ T *old_start = containers_detail::get_pointer(this->members_.m_start);
+ size_type old_size = this->members_.m_size;
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
+ //If something goes wrong size will be 0
+ //but holding the whole buffer
+ this->members_.m_size = 0;
+ this->members_.m_start = ret.first;
+ this->members_.m_capacity = real_cap;
+
+ //Backup old buffer data
+ size_type old_offset = old_start - containers_detail::get_pointer(ret.first);
+ size_type first_count = containers_detail::min_value(n, old_offset);
+
+ FwdIt mid = first;
+ std::advance(mid, first_count);
+ // iG std::uninitialized_copy(first, mid, containers_detail::get_pointer(ret.first));
+ boost::interprocess::uninitialized_copy_or_move(first, mid, containers_detail::get_pointer(ret.first));
+
+ if(old_offset > n){
+ //All old elements will be destroyed by "old_values_destroyer"
+ this->members_.m_size = n;
+ }
+ else{
+ //We have constructed objects from the new begin until
+ //the old end so release the rollback destruction
+ old_values_destroyer.release();
+ this->members_.m_start = ret.first;
+ this->members_.m_size = first_count + old_size;
+ //Now overwrite the old values
+ size_type second_count = containers_detail::min_value(old_size, n - first_count);
+ FwdIt mid2 = mid;
+ std::advance(mid2, second_count);
+ // iG std::copy(mid, mid2, old_start);
+ std::copy(mid, mid2, old_start);
+
+ //Check if we still have to append elements in the
+ //uninitialized end
+ if(second_count == old_size){
+ // iG std::copy(mid2, last, old_start + old_size);
+ std::copy(mid2, last, old_start + old_size);
+ }
+ else{
+ //We have to destroy some old values
+ this->destroy_n
+ (old_start + second_count, old_size - second_count);
+ this->members_.m_size = n;
+ }
+ this->members_.m_size = n;
+ }
+ }
+ }
+
+ template <class Integer>
+ void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
+ { this->assign((size_type) n, (T) val); }
+
+ template <class InIt>
+ void priv_assign_dispatch(InIt first, InIt last, containers_detail::false_)
+ {
+ //Dispatch depending on integer/iterator
+ typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
+ this->priv_assign_aux(first, last, ItCat());
+ }
+
+ template <class Integer>
+ void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, containers_detail::true_)
+ { this->insert(pos, (size_type)n, (T)val); }
+
+ template <class InIt>
+ void priv_insert_dispatch(const_iterator pos, InIt first,
+ InIt last, containers_detail::false_)
+ {
+ //Dispatch depending on integer/iterator
+ typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
+ this->priv_range_insert(pos.get_ptr(), first, last, ItCat());
+ }
+
+ void priv_check_range(size_type n) const
+ {
+ //If n is out of range, throw an out_of_range exception
+ if (n >= size())
+ throw std::out_of_range("vector::at");
+ }
+
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ public:
+ unsigned int num_expand_fwd;
+ unsigned int num_expand_bwd;
+ unsigned int num_shrink;
+ unsigned int num_alloc;
+ void reset_alloc_stats()
+ { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
+ #endif
+ /// @endcond
+};
+
+template <class T, class A>
+inline bool
+operator==(const vector<T, A>& x, const vector<T, A>& y)
+{
+ //Check first size and each element if needed
+ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class A>
+inline bool
+operator!=(const vector<T, A>& x, const vector<T, A>& y)
+{
+ //Check first size and each element if needed
+ return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class A>
+inline bool
+operator<(const vector<T, A>& x, const vector<T, A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T, class A>
+inline void swap(vector<T, A>& x, vector<T, A>& y)
+{ x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+namespace interprocess {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::interprocess_container::vector<T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+
+}}
+
+/// @endcond
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_CONTAINERS_CONTAINERS_VECTOR_HPP
+
Modified: trunk/boost/interprocess/containers/deque.hpp
==============================================================================
--- trunk/boost/interprocess/containers/deque.hpp (original)
+++ trunk/boost/interprocess/containers/deque.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,1538 +1,32 @@
-/*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2006. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_deque.h and stl_uninitialized.h files.
-// Modified by Ion Gaztanaga 2005.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTERPROCESS_DEQUE_HPP
-#define BOOST_INTERPROCESS_DEQUE_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_DEQUE_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_DEQUE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
-#include <boost/interprocess/detail/min_max.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <cstddef>
-#include <iterator>
-#include <cassert>
-#include <memory>
-#include <algorithm>
-#include <stdexcept>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/type_traits/has_nothrow_copy.hpp>
-#include <boost/type_traits/has_nothrow_assign.hpp>
-#include <boost/interprocess/detail/move_iterator.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/advanced_insert_int.hpp>
+#include <boost/interprocess/containers/container/deque.hpp>
namespace boost {
namespace interprocess {
-/// @cond
-template <class T, class Alloc>
-class deque;
-
-template <class T, class A>
-struct deque_value_traits
-{
- typedef T value_type;
- typedef A allocator_type;
- static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move =
- has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
- static const bool trivial_copy = has_trivial_copy<value_type>::value;
- static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
- static const bool trivial_assign = has_trivial_assign<value_type>::value;
- static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
-
-};
-
-// Note: this function is simply a kludge to work around several compilers'
-// bugs in handling constant expressions.
-inline std::size_t deque_buf_size(std::size_t size)
- { return size < 512 ? std::size_t(512 / size) : std::size_t(1); }
-
-// Deque base class. It has two purposes. First, its constructor
-// and destructor allocate (but don't initialize) storage. This makes
-// exception safety easier.
-template <class T, class Alloc>
-class deque_base
-{
- public:
- typedef typename Alloc::value_type val_alloc_val;
- typedef typename Alloc::pointer val_alloc_ptr;
- typedef typename Alloc::const_pointer val_alloc_cptr;
- typedef typename Alloc::reference val_alloc_ref;
- typedef typename Alloc::const_reference val_alloc_cref;
- typedef typename Alloc::value_type val_alloc_diff;
- typedef typename Alloc::template rebind
- <typename Alloc::pointer>::other ptr_alloc_t;
- typedef typename ptr_alloc_t::value_type ptr_alloc_val;
- typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
- typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
- typedef typename ptr_alloc_t::reference ptr_alloc_ref;
- typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
- typedef typename Alloc::template
- rebind<T>::other allocator_type;
- typedef allocator_type stored_allocator_type;
-
- protected:
-
- typedef deque_value_traits<T, Alloc> traits_t;
- typedef typename Alloc::template
- rebind<typename Alloc::pointer>::other map_allocator_type;
-
- static std::size_t s_buffer_size() { return deque_buf_size(sizeof(T)); }
-
- val_alloc_ptr priv_allocate_node()
- { return this->alloc().allocate(s_buffer_size()); }
-
- void priv_deallocate_node(val_alloc_ptr p)
- { this->alloc().deallocate(p, s_buffer_size()); }
-
- ptr_alloc_ptr priv_allocate_map(std::size_t n)
- { return this->ptr_alloc().allocate(n); }
-
- void priv_deallocate_map(ptr_alloc_ptr p, std::size_t n)
- { this->ptr_alloc().deallocate(p, n); }
-
- public:
- // Class invariants:
- // For any nonsingular iterator i:
- // i.node is the address of an element in the map array. The
- // contents of i.node is a pointer to the beginning of a node.
- // i.first == //(i.node)
- // i.last == i.first + node_size
- // i.cur is a pointer in the range [i.first, i.last). NOTE:
- // the implication of this is that i.cur is always a dereferenceable
- // pointer, even if i is a past-the-end iterator.
- // Start and Finish are always nonsingular iterators. NOTE: this means
- // that an empty deque must have one node, and that a deque
- // with N elements, where N is the buffer size, must have two nodes.
- // For every node other than start.node and finish.node, every element
- // in the node is an initialized object. If start.node == finish.node,
- // then [start.cur, finish.cur) are initialized objects, and
- // the elements outside that range are uninitialized storage. Otherwise,
- // [start.cur, start.last) and [finish.first, finish.cur) are initialized
- // objects, and [start.first, start.cur) and [finish.cur, finish.last)
- // are uninitialized storage.
- // [map, map + map_size) is a valid, non-empty range.
- // [start.node, finish.node] is a valid range contained within
- // [map, map + map_size).
- // A pointer in the range [map, map + map_size) points to an allocated node
- // if and only if the pointer is in the range [start.node, finish.node].
- class const_iterator
- : public std::iterator<std::random_access_iterator_tag,
- val_alloc_val, val_alloc_diff,
- val_alloc_cptr, val_alloc_cref>
- {
- public:
- static std::size_t s_buffer_size() { return deque_base<T, Alloc>::s_buffer_size(); }
-
- typedef std::random_access_iterator_tag iterator_category;
- typedef val_alloc_val value_type;
- typedef val_alloc_cptr pointer;
- typedef val_alloc_cref reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- typedef ptr_alloc_ptr index_pointer;
- typedef const_iterator self_t;
-
- friend class deque<T, Alloc>;
- friend class deque_base<T, Alloc>;
-
- protected:
- val_alloc_ptr m_cur;
- val_alloc_ptr m_first;
- val_alloc_ptr m_last;
- index_pointer m_node;
-
- public:
- const_iterator(val_alloc_ptr x, index_pointer y)
- : m_cur(x), m_first(*y),
- m_last(*y + s_buffer_size()), m_node(y) {}
-
- const_iterator() : m_cur(0), m_first(0), m_last(0), m_node(0) {}
-
- const_iterator(const const_iterator& x)
- : m_cur(x.m_cur), m_first(x.m_first),
- m_last(x.m_last), m_node(x.m_node) {}
-
- reference operator*() const
- { return *this->m_cur; }
-
- pointer operator->() const
- { return this->m_cur; }
-
- difference_type operator-(const self_t& x) const
- {
- if(!this->m_cur && !x.m_cur){
- return 0;
- }
- return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
- (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
- }
-
- self_t& operator++()
- {
- ++this->m_cur;
- if (this->m_cur == this->m_last) {
- this->priv_set_node(this->m_node + 1);
- this->m_cur = this->m_first;
- }
- return *this;
- }
-
- self_t operator++(int)
- {
- self_t tmp = *this;
- ++*this;
- return tmp;
- }
-
- self_t& operator--()
- {
- if (this->m_cur == this->m_first) {
- this->priv_set_node(this->m_node - 1);
- this->m_cur = this->m_last;
- }
- --this->m_cur;
- return *this;
- }
-
- self_t operator--(int)
- {
- self_t tmp = *this;
- --*this;
- return tmp;
- }
-
- self_t& operator+=(difference_type n)
- {
- difference_type offset = n + (this->m_cur - this->m_first);
- if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
- this->m_cur += n;
- else {
- difference_type node_offset =
- offset > 0 ? offset / difference_type(this->s_buffer_size())
- : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
- this->priv_set_node(this->m_node + node_offset);
- this->m_cur = this->m_first +
- (offset - node_offset * difference_type(this->s_buffer_size()));
- }
- return *this;
- }
-
- self_t operator+(difference_type n) const
- { self_t tmp = *this; return tmp += n; }
-
- self_t& operator-=(difference_type n)
- { return *this += -n; }
-
- self_t operator-(difference_type n) const
- { self_t tmp = *this; return tmp -= n; }
-
- reference operator[](difference_type n) const
- { return *(*this + n); }
-
- bool operator==(const self_t& x) const
- { return this->m_cur == x.m_cur; }
-
- bool operator!=(const self_t& x) const
- { return !(*this == x); }
-
- bool operator<(const self_t& x) const
- {
- return (this->m_node == x.m_node) ?
- (this->m_cur < x.m_cur) : (this->m_node < x.m_node);
- }
-
- bool operator>(const self_t& x) const
- { return x < *this; }
-
- bool operator<=(const self_t& x) const
- { return !(x < *this); }
-
- bool operator>=(const self_t& x) const
- { return !(*this < x); }
-
- void priv_set_node(index_pointer new_node)
- {
- this->m_node = new_node;
- this->m_first = *new_node;
- this->m_last = this->m_first + difference_type(this->s_buffer_size());
- }
-
- friend const_iterator operator+(std::ptrdiff_t n, const const_iterator& x)
- { return x + n; }
- };
-
- //Deque iterator
- class iterator : public const_iterator
- {
- public:
- typedef std::random_access_iterator_tag iterator_category;
- typedef val_alloc_val value_type;
- typedef val_alloc_ptr pointer;
- typedef val_alloc_ref reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef ptr_alloc_ptr index_pointer;
- typedef const_iterator self_t;
-
- friend class deque<T, Alloc>;
- friend class deque_base<T, Alloc>;
-
- private:
- explicit iterator(const const_iterator& x) : const_iterator(x){}
-
- public:
- //Constructors
- iterator(val_alloc_ptr x, index_pointer y) : const_iterator(x, y){}
- iterator() : const_iterator(){}
- //iterator(const const_iterator &cit) : const_iterator(cit){}
- iterator(const iterator& x) : const_iterator(x){}
-
- //Pointer like operators
- reference operator*() const { return *this->m_cur; }
- pointer operator->() const { return this->m_cur; }
-
- reference operator[](difference_type n) const { return *(*this + n); }
-
- //Increment / Decrement
- iterator& operator++()
- { this->const_iterator::operator++(); return *this; }
-
- iterator operator++(int)
- { iterator tmp = *this; ++*this; return tmp; }
-
- iterator& operator--()
- { this->const_iterator::operator--(); return *this; }
-
- iterator operator--(int)
- { iterator tmp = *this; --*this; return tmp; }
-
- // Arithmetic
- iterator& operator+=(difference_type off)
- { this->const_iterator::operator+=(off); return *this; }
-
- iterator operator+(difference_type off) const
- { return iterator(this->const_iterator::operator+(off)); }
-
- friend iterator operator+(difference_type off, const iterator& right)
- { return iterator(off+static_cast<const const_iterator &>(right)); }
-
- iterator& operator-=(difference_type off)
- { this->const_iterator::operator-=(off); return *this; }
-
- iterator operator-(difference_type off) const
- { return iterator(this->const_iterator::operator-(off)); }
-
- difference_type operator-(const const_iterator& right) const
- { return static_cast<const const_iterator&>(*this) - right; }
- };
-
- deque_base(const allocator_type& a, std::size_t num_elements)
- : members_(a)
- { this->priv_initialize_map(num_elements); }
-
- deque_base(const allocator_type& a)
- : members_(a)
- {}
-
- ~deque_base()
- {
- if (this->members_.m_map) {
- this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
- }
- }
-
- private:
- deque_base(const deque_base&);
-
- protected:
-
- void priv_initialize_map(std::size_t num_elements)
- {
-// if(num_elements){
- std::size_t num_nodes = num_elements / s_buffer_size() + 1;
-
- this->members_.m_map_size = max_value((std::size_t) InitialMapSize, num_nodes + 2);
- this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
-
- ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
- ptr_alloc_ptr nfinish = nstart + num_nodes;
-
- BOOST_TRY {
- this->priv_create_nodes(nstart, nfinish);
- }
- BOOST_CATCH(...){
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
- this->members_.m_map = 0;
- this->members_.m_map_size = 0;
- BOOST_RETHROW
- }
- BOOST_CATCH_END
-
- this->members_.m_start.priv_set_node(nstart);
- this->members_.m_finish.priv_set_node(nfinish - 1);
- this->members_.m_start.m_cur = this->members_.m_start.m_first;
- this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
- num_elements % s_buffer_size();
-// }
- }
-
- void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
- {
- ptr_alloc_ptr cur;
- BOOST_TRY {
- for (cur = nstart; cur < nfinish; ++cur)
- *cur = this->priv_allocate_node();
- }
- BOOST_CATCH(...){
- this->priv_destroy_nodes(nstart, cur);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
- {
- for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
- this->priv_deallocate_node(*n);
- }
-
- enum { InitialMapSize = 8 };
-
- protected:
- struct members_holder
- : public ptr_alloc_t
- , public allocator_type
- {
- members_holder(const allocator_type &a)
- : map_allocator_type(a), allocator_type(a)
- , m_map(0), m_map_size(0)
- , m_start(), m_finish(m_start)
- {}
-
- ptr_alloc_ptr m_map;
- std::size_t m_map_size;
- iterator m_start;
- iterator m_finish;
- } members_;
-
- ptr_alloc_t &ptr_alloc()
- { return members_; }
-
- const ptr_alloc_t &ptr_alloc() const
- { return members_; }
-
- allocator_type &alloc()
- { return members_; }
-
- const allocator_type &alloc() const
- { return members_; }
-};
-/// @endcond
-
-//! Deque class
-//!
-template <class T, class Alloc>
-class deque : protected deque_base<T, Alloc>
-{
- /// @cond
- typedef deque_base<T, Alloc> Base;
-
- public: // Basic types
- typedef typename Alloc::value_type val_alloc_val;
- typedef typename Alloc::pointer val_alloc_ptr;
- typedef typename Alloc::const_pointer val_alloc_cptr;
- typedef typename Alloc::reference val_alloc_ref;
- typedef typename Alloc::const_reference val_alloc_cref;
- typedef typename Alloc::template
- rebind<val_alloc_ptr>::other ptr_alloc_t;
- typedef typename ptr_alloc_t::value_type ptr_alloc_val;
- typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
- typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
- typedef typename ptr_alloc_t::reference ptr_alloc_ref;
- typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
- /// @endcond
-
- typedef T value_type;
- typedef val_alloc_ptr pointer;
- typedef val_alloc_cptr const_pointer;
- typedef val_alloc_ref reference;
- typedef val_alloc_cref const_reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- typedef typename Base::allocator_type allocator_type;
-
- public: // Iterators
- typedef typename Base::iterator iterator;
- typedef typename Base::const_iterator const_iterator;
-
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- /// @cond
- private: // Internal typedefs
- typedef ptr_alloc_ptr index_pointer;
- static std::size_t s_buffer_size()
- { return Base::s_buffer_size(); }
- typedef detail::advanced_insert_aux_int<value_type, iterator> advanced_insert_aux_int_t;
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef detail::move_iterator<r_iterator> move_it;
-
- /// @endcond
-
- allocator_type get_allocator() const { return Base::alloc(); }
-
- public: // Basic accessors
- iterator begin()
- { return this->members_.m_start; }
-
- iterator end()
- { return this->members_.m_finish; }
-
- const_iterator begin() const
- { return this->members_.m_start; }
-
- const_iterator end() const
- { return this->members_.m_finish; }
-
- reverse_iterator rbegin()
- { return reverse_iterator(this->members_.m_finish); }
-
- reverse_iterator rend()
- { return reverse_iterator(this->members_.m_start); }
-
- const_reverse_iterator rbegin() const
- { return const_reverse_iterator(this->members_.m_finish); }
-
- const_reverse_iterator rend() const
- { return const_reverse_iterator(this->members_.m_start); }
-
- const_iterator cbegin() const
- { return this->members_.m_start; }
-
- const_iterator cend() const
- { return this->members_.m_finish; }
-
- const_reverse_iterator crbegin() const
- { return const_reverse_iterator(this->members_.m_finish); }
-
- const_reverse_iterator crend() const
- { return const_reverse_iterator(this->members_.m_start); }
-
- reference operator[](size_type n)
- { return this->members_.m_start[difference_type(n)]; }
-
- const_reference operator[](size_type n) const
- { return this->members_.m_start[difference_type(n)]; }
-
- void priv_range_check(size_type n) const
- { if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
-
- reference at(size_type n)
- { this->priv_range_check(n); return (*this)[n]; }
-
- const_reference at(size_type n) const
- { this->priv_range_check(n); return (*this)[n]; }
-
- reference front() { return *this->members_.m_start; }
-
- reference back() { return *(end()-1); }
-
- const_reference front() const
- { return *this->members_.m_start; }
-
- const_reference back() const { return *(cend()-1); }
-
- size_type size() const
- { return this->members_.m_finish - this->members_.m_start; }
-
- size_type max_size() const
- { return this->alloc().max_size(); }
-
- bool empty() const
- { return this->members_.m_finish == this->members_.m_start; }
-
- explicit deque(const allocator_type& a = allocator_type())
- : Base(a)
- {}
-
- deque(const deque& x)
- : Base(x.alloc())
- {
- if(x.size()){
- this->priv_initialize_map(x.size());
- std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start);
- }
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- deque(detail::moved_object<deque> mx)
- : Base(mx.get().alloc())
- { this->swap(mx.get()); }
- #else
- deque(deque &&x)
- : Base(x.alloc())
- { this->swap(x); }
- #endif
-
- deque(size_type n, const value_type& value,
- const allocator_type& a = allocator_type()) : Base(a, n)
- { this->priv_fill_initialize(value); }
-
- explicit deque(size_type n) : Base(allocator_type(), n)
- { this->resize(n); }
-
- // Check whether it's an integral type. If so, it's not an iterator.
- template <class InpIt>
- deque(InpIt first, InpIt last, const allocator_type& a = allocator_type())
- : Base(a)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_initialize_dispatch(first, last, Result());
- }
-
- ~deque()
- {
- priv_destroy_range(this->members_.m_start, this->members_.m_finish);
- }
-
- deque& operator= (const deque& x)
- {
- const size_type len = size();
- if (&x != this) {
- if (len >= x.size())
- this->erase(std::copy(x.begin(), x.end(), this->members_.m_start), this->members_.m_finish);
- else {
- const_iterator mid = x.begin() + difference_type(len);
- std::copy(x.begin(), mid, this->members_.m_start);
- this->insert(this->members_.m_finish, mid, x.end());
- }
- }
- return *this;
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- deque& operator= (detail::moved_object<deque> mx)
- {
- deque &x = mx.get();
- #else
- deque& operator= (deque &&x)
- {
- #endif
- this->clear();
- this->swap(x);
- return *this;
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<deque> x)
- { this->swap(x.get()); }
- void swap(deque& x)
- #else
- void swap(deque &&x)
- #endif
- {
- std::swap(this->members_.m_start, x.members_.m_start);
- std::swap(this->members_.m_finish, x.members_.m_finish);
- std::swap(this->members_.m_map, x.members_.m_map);
- std::swap(this->members_.m_map_size, x.members_.m_map_size);
- }
-
- void assign(size_type n, const T& val)
- { this->priv_fill_assign(n, val); }
-
- template <class InpIt>
- void assign(InpIt first, InpIt last)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
- }
-
- void push_back(const value_type& t)
- {
- if(this->priv_push_back_simple_available()){
- new(this->priv_push_back_simple_pos())value_type(t);
- this->priv_push_back_simple_commit();
- }
- else{
- this->priv_insert_aux(cend(), size_type(1), t);
- }
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void push_back(detail::moved_object<value_type> mt)
- {
- value_type &t = mt.get();
- #else
- void push_back(value_type &&t)
- {
- #endif
- if(this->priv_push_back_simple_available()){
- new(this->priv_push_back_simple_pos())value_type(detail::move_impl(t));
- this->priv_push_back_simple_commit();
- }
- else{
- this->priv_insert_aux(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
- }
- }
-
- void push_front(const value_type& t)
- {
- if(this->priv_push_front_simple_available()){
- new(this->priv_push_front_simple_pos())value_type(t);
- this->priv_push_front_simple_commit();
- }
- else{
- this->priv_insert_aux(cbegin(), size_type(1), t);
- }
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void push_front(detail::moved_object<value_type> mt)
- {
- value_type &t = mt.get();
- #else
- void push_front(value_type &&t)
- {
- #endif
- if(this->priv_push_front_simple_available()){
- new(this->priv_push_front_simple_pos())value_type(detail::move_impl(t));
- this->priv_push_front_simple_commit();
- }
- else{
- this->priv_insert_aux(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
- }
- }
-
- void pop_back()
- {
- if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
- --this->members_.m_finish.m_cur;
- detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
- }
- else
- this->priv_pop_back_aux();
- }
-
- void pop_front()
- {
- if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
- detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
- ++this->members_.m_start.m_cur;
- }
- else
- this->priv_pop_front_aux();
- }
-
- iterator insert(const_iterator position, const value_type& x)
- {
- if (position == cbegin()){
- this->push_front(x);
- return begin();
- }
- else if (position == cend()){
- this->push_back(x);
- return (end()-1);
- }
- else {
- size_type n = position - cbegin();
- this->priv_insert_aux(position, size_type(1), x);
- return iterator(this->begin() + n);
- }
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, detail::moved_object<value_type> m)
- {
- value_type &mx = m.get();
- #else
- iterator insert(const_iterator position, value_type &&mx)
- {
- #endif
- if (position == cbegin()) {
- this->push_front(detail::move_impl(mx));
- return begin();
- }
- else if (position == cend()) {
- this->push_back(detail::move_impl(mx));
- return(end()-1);
- }
- else {
- //Just call more general insert(pos, size, value) and return iterator
- size_type n = position - begin();
- this->priv_insert_aux(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
- return iterator(this->begin() + n);
- }
- }
-
- void insert(const_iterator pos, size_type n, const value_type& x)
- { this->priv_fill_insert(pos, n, x); }
-
- // Check whether it's an integral type. If so, it's not an iterator.
- template <class InpIt>
- void insert(const_iterator pos, InpIt first, InpIt last)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(pos, first, last, Result());
- }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template <class... Args>
- void emplace_back(Args&&... args)
- {
- if(this->priv_push_back_simple_available()){
- new(this->priv_push_back_simple_pos())value_type(detail::forward_impl<Args>(args)...);
- this->priv_push_back_simple_commit();
- }
- else{
- detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(detail::forward_impl<Args>(args)...);
- this->priv_insert_aux_impl(this->cend(), 1, proxy);
- }
- }
-
- template <class... Args>
- void emplace_front(Args&&... args)
- {
- if(this->priv_push_front_simple_available()){
- new(this->priv_push_front_simple_pos())value_type(detail::forward_impl<Args>(args)...);
- this->priv_push_front_simple_commit();
- }
- else{
- detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(detail::forward_impl<Args>(args)...);
- this->priv_insert_aux_impl(this->cbegin(), 1, proxy);
- }
- }
-
- template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
- {
- if(p == this->cbegin()){
- this->emplace_front(detail::forward_impl<Args>(args)...);
- return this->begin();
- }
- else if(p == this->cend()){
- this->emplace_back(detail::forward_impl<Args>(args)...);
- return (this->end()-1);
- }
- else{
- size_type n = p - this->cbegin();
- detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(detail::forward_impl<Args>(args)...);
- this->priv_insert_aux_impl(p, 1, proxy);
- return iterator(this->begin() + n);
- }
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //0 args
- void emplace_back()
- {
- if(priv_push_front_simple_available()){
- new(priv_push_front_simple_pos())value_type();
- priv_push_front_simple_commit();
- }
- else{
- detail::advanced_insert_aux_emplace<T, iterator> proxy;
- priv_insert_aux_impl(cend(), 1, proxy);
- }
- }
-
- void emplace_front()
- {
- if(priv_push_front_simple_available()){
- new(priv_push_front_simple_pos())value_type();
- priv_push_front_simple_commit();
- }
- else{
- detail::advanced_insert_aux_emplace<T, iterator> proxy;
- priv_insert_aux_impl(cbegin(), 1, proxy);
- }
- }
-
- iterator emplace(const_iterator p)
- {
- if(p == cbegin()){
- emplace_front();
- return begin();
- }
- else if(p == cend()){
- emplace_back();
- return (end()-1);
- }
- else{
- size_type n = p - cbegin();
- detail::advanced_insert_aux_emplace<T, iterator> proxy;
- priv_insert_aux_impl(p, 1, proxy);
- return iterator(this->begin() + n);
- }
- }
-
- //advanced_insert_int.hpp includes all necessary preprocessor machinery...
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- if(priv_push_back_simple_available()){ \
- new(priv_push_back_simple_pos())value_type \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- priv_push_back_simple_commit(); \
- } \
- else{ \
- detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
- proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- priv_insert_aux_impl(cend(), 1, proxy); \
- } \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- if(priv_push_front_simple_available()){ \
- new(priv_push_front_simple_pos())value_type \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- priv_push_front_simple_commit(); \
- } \
- else{ \
- detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
- proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- priv_insert_aux_impl(cbegin(), 1, proxy); \
- } \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- if(p == this->cbegin()){ \
- this->emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- return this->begin(); \
- } \
- else if(p == cend()){ \
- this->emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- return (this->end()-1); \
- } \
- else{ \
- size_type pos_num = p - this->cbegin(); \
- detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
- proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- this->priv_insert_aux_impl(p, 1, proxy); \
- return iterator(this->begin() + pos_num); \
- } \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- void resize(size_type new_size, const value_type& x)
- {
- const size_type len = size();
- if (new_size < len)
- this->erase(this->members_.m_start + new_size, this->members_.m_finish);
- else
- this->insert(this->members_.m_finish, new_size - len, x);
- }
-
- void resize(size_type new_size)
- {
- const size_type len = size();
- if (new_size < len)
- this->erase(this->members_.m_start + new_size, this->members_.m_finish);
- else{
- size_type n = new_size - this->size();
- detail::default_construct_aux_proxy<T, iterator, size_type> proxy(n);
- priv_insert_aux_impl(this->cend(), n, proxy);
- }
- }
-
- iterator erase(const_iterator pos)
- {
- const_iterator next = pos;
- ++next;
- difference_type index = pos - this->members_.m_start;
- if (size_type(index) < (this->size() >> 1)) {
- std::copy_backward( detail::make_move_iterator(begin())
- , detail::make_move_iterator(iterator(pos))
- , iterator(next));
- pop_front();
- }
- else {
- std::copy( detail::make_move_iterator(iterator(next))
- , detail::make_move_iterator(end())
- , iterator(pos));
- pop_back();
- }
- return this->members_.m_start + index;
- }
-
- iterator erase(const_iterator first, const_iterator last)
- {
- if (first == this->members_.m_start && last == this->members_.m_finish) {
- this->clear();
- return this->members_.m_finish;
- }
- else {
- difference_type n = last - first;
- difference_type elems_before = first - this->members_.m_start;
- if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
- std::copy_backward( detail::make_move_iterator(begin())
- , detail::make_move_iterator(iterator(first))
- , iterator(last));
- iterator new_start = this->members_.m_start + n;
- if(!Base::traits_t::trivial_dctr_after_move)
- this->priv_destroy_range(this->members_.m_start, new_start);
- this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
- this->members_.m_start = new_start;
- }
- else {
- std::copy( detail::make_move_iterator(iterator(last))
- , detail::make_move_iterator(end())
- , iterator(first));
- iterator new_finish = this->members_.m_finish - n;
- if(!Base::traits_t::trivial_dctr_after_move)
- this->priv_destroy_range(new_finish, this->members_.m_finish);
- this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
- this->members_.m_finish = new_finish;
- }
- return this->members_.m_start + elems_before;
- }
- }
-
- void clear()
- {
- for (index_pointer node = this->members_.m_start.m_node + 1;
- node < this->members_.m_finish.m_node;
- ++node) {
- this->priv_destroy_range(*node, *node + this->s_buffer_size());
- this->priv_deallocate_node(*node);
- }
-
- if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
- this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
- this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
- this->priv_deallocate_node(this->members_.m_finish.m_first);
- }
- else
- this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
-
- this->members_.m_finish = this->members_.m_start;
- }
-
- /// @cond
- private:
-
- bool priv_push_back_simple_available() const
- {
- return this->members_.m_map &&
- (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
- }
-
- void *priv_push_back_simple_pos() const
- {
- return static_cast<void*>(detail::get_pointer(this->members_.m_finish.m_cur));
- }
-
- void priv_push_back_simple_commit()
- {
- ++this->members_.m_finish.m_cur;
- }
-
- bool priv_push_front_simple_available() const
- {
- return this->members_.m_map &&
- (this->members_.m_start.m_cur != this->members_.m_start.m_first);
- }
-
- void *priv_push_front_simple_pos() const
- { return static_cast<void*>(detail::get_pointer(this->members_.m_start.m_cur) - 1); }
-
- void priv_push_front_simple_commit()
- { --this->members_.m_start.m_cur; }
-
- template <class InpIt>
- void priv_insert_aux(const_iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
- {
- for(;first != last; ++first){
- this->insert(pos, move_impl(value_type(*first)));
- }
- }
-
- template <class FwdIt>
- void priv_insert_aux(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
- { this->priv_insert_aux(pos, first, last); }
-
- // assign(), a generalized assignment member function. Two
- // versions: one that takes a count, and one that takes a range.
- // The range version is a member template, so we dispatch on whether
- // or not the type is an integer.
- void priv_fill_assign(size_type n, const T& val)
- {
- if (n > size()) {
- std::fill(begin(), end(), val);
- this->insert(cend(), n - size(), val);
- }
- else {
- this->erase(cbegin() + n, cend());
- std::fill(begin(), end(), val);
- }
- }
-
- template <class Integer>
- void priv_initialize_dispatch(Integer n, Integer x, detail::true_)
- {
- this->priv_initialize_map(n);
- this->priv_fill_initialize(x);
- }
-
- template <class InpIt>
- void priv_initialize_dispatch(InpIt first, InpIt last, detail::false_)
- {
- typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->priv_range_initialize(first, last, ItCat());
- }
-
- void priv_destroy_range(iterator p, iterator p2)
- {
- for(;p != p2; ++p)
- detail::get_pointer(&*p)->~value_type();
- }
-
- void priv_destroy_range(pointer p, pointer p2)
- {
- for(;p != p2; ++p)
- detail::get_pointer(&*p)->~value_type();
- }
-
- template <class Integer>
- void priv_assign_dispatch(Integer n, Integer val, detail::true_)
- { this->priv_fill_assign((size_type) n, (T) val); }
-
- template <class InpIt>
- void priv_assign_dispatch(InpIt first, InpIt last, detail::false_)
- {
- typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->priv_assign_aux(first, last, ItCat());
- }
-
- template <class InpIt>
- void priv_assign_aux(InpIt first, InpIt last, std::input_iterator_tag)
- {
- iterator cur = begin();
- for ( ; first != last && cur != end(); ++cur, ++first)
- *cur = *first;
- if (first == last)
- this->erase(cur, cend());
- else
- this->insert(cend(), first, last);
- }
-
- template <class FwdIt>
- void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- size_type len = std::distance(first, last);
- if (len > size()) {
- FwdIt mid = first;
- std::advance(mid, size());
- std::copy(first, mid, begin());
- this->insert(cend(), mid, last);
- }
- else
- this->erase(std::copy(first, last, begin()), cend());
- }
-
- template <class Integer>
- void priv_insert_dispatch(const_iterator pos, Integer n, Integer x, detail::true_)
- { this->priv_fill_insert(pos, (size_type) n, (value_type) x); }
-
- template <class InpIt>
- void priv_insert_dispatch(const_iterator pos,InpIt first, InpIt last, detail::false_)
- {
- typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->priv_insert_aux(pos, first, last, ItCat());
- }
-
- void priv_insert_aux(const_iterator pos, size_type n, const value_type& x)
- {
- typedef constant_iterator<value_type, difference_type> c_it;
- this->priv_insert_aux(pos, c_it(x, n), c_it());
- }
-
- //Just forward all operations to priv_insert_aux_impl
- template <class FwdIt>
- void priv_insert_aux(const_iterator p, FwdIt first, FwdIt last)
- {
- detail::advanced_insert_aux_proxy<T, FwdIt, iterator> proxy(first, last);
- priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
- }
-
- void priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
- {
- iterator pos(p);
- if(!this->members_.m_map){
- this->priv_initialize_map(0);
- pos = this->begin();
- }
-
- const difference_type elemsbefore = pos - this->members_.m_start;
- size_type length = this->size();
- if (elemsbefore < static_cast<difference_type>(length / 2)) {
- iterator new_start = this->priv_reserve_elements_at_front(n);
- iterator old_start = this->members_.m_start;
- pos = this->members_.m_start + elemsbefore;
- if (elemsbefore >= difference_type(n)) {
- iterator start_n = this->members_.m_start + difference_type(n);
- std::uninitialized_copy(detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(start_n), new_start);
- this->members_.m_start = new_start;
- std::copy(detail::make_move_iterator(start_n), detail::make_move_iterator(pos), old_start);
- interf.copy_all_to(pos - difference_type(n));
- }
- else {
- difference_type mid_count = (difference_type(n) - elemsbefore);
- iterator mid_start = old_start - mid_count;
- interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
- this->members_.m_start = mid_start;
- std::uninitialized_copy(detail::make_move_iterator(old_start), detail::make_move_iterator(pos), new_start);
- this->members_.m_start = new_start;
- interf.copy_all_to(old_start);
- }
- }
- else {
- iterator new_finish = this->priv_reserve_elements_at_back(n);
- iterator old_finish = this->members_.m_finish;
- const difference_type elemsafter =
- difference_type(length) - elemsbefore;
- pos = this->members_.m_finish - elemsafter;
- if (elemsafter >= difference_type(n)) {
- iterator finish_n = this->members_.m_finish - difference_type(n);
- std::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish);
- this->members_.m_finish = new_finish;
- std::copy_backward(detail::make_move_iterator(pos), detail::make_move_iterator(finish_n), old_finish);
- interf.copy_all_to(pos);
- }
- else {
- interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
- this->members_.m_finish += n-elemsafter;
- std::uninitialized_copy(detail::make_move_iterator(pos), detail::make_move_iterator(old_finish), this->members_.m_finish);
- this->members_.m_finish = new_finish;
- interf.copy_all_to(pos);
- }
- }
- }
-
- void priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
- {
- typedef constant_iterator<value_type, difference_type> c_it;
- this->insert(pos, c_it(x, n), c_it());
- }
-
- // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
- // but none of the deque's elements have yet been constructed.
- void priv_fill_initialize(const value_type& value)
- {
- index_pointer cur;
- BOOST_TRY {
- for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
- std::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
- }
- std::uninitialized_fill(this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
- }
- BOOST_CATCH(...){
- this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- template <class InpIt>
- void priv_range_initialize(InpIt first, InpIt last, std::input_iterator_tag)
- {
- this->priv_initialize_map(0);
- BOOST_TRY {
- for ( ; first != last; ++first)
- this->push_back(*first);
- }
- BOOST_CATCH(...){
- this->clear();
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- template <class FwdIt>
- void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- size_type n = 0;
- n = std::distance(first, last);
- this->priv_initialize_map(n);
-
- index_pointer cur_node;
- BOOST_TRY {
- for (cur_node = this->members_.m_start.m_node;
- cur_node < this->members_.m_finish.m_node;
- ++cur_node) {
- FwdIt mid = first;
- std::advance(mid, this->s_buffer_size());
- std::uninitialized_copy(first, mid, *cur_node);
- first = mid;
- }
- std::uninitialized_copy(first, last, this->members_.m_finish.m_first);
- }
- BOOST_CATCH(...){
- this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
- void priv_pop_back_aux()
- {
- this->priv_deallocate_node(this->members_.m_finish.m_first);
- this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
- this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
- detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
- }
-
- // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
- // if the deque has at least one element (a precondition for this member
- // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
- // must have at least two nodes.
- void priv_pop_front_aux()
- {
- detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
- this->priv_deallocate_node(this->members_.m_start.m_first);
- this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
- this->members_.m_start.m_cur = this->members_.m_start.m_first;
- }
-
- iterator priv_reserve_elements_at_front(size_type n)
- {
- size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
- if (n > vacancies){
- size_type new_elems = n-vacancies;
- size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
- this->s_buffer_size();
- size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
- if (new_nodes > s){
- this->priv_reallocate_map(new_nodes, true);
- }
- size_type i = 1;
- BOOST_TRY {
- for (; i <= new_nodes; ++i)
- *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
- }
- BOOST_CATCH(...) {
- for (size_type j = 1; j < i; ++j)
- this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- return this->members_.m_start - difference_type(n);
- }
-
- iterator priv_reserve_elements_at_back(size_type n)
- {
- size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
- if (n > vacancies){
- size_type new_elems = n - vacancies;
- size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
- size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
- if (new_nodes + 1 > s){
- this->priv_reallocate_map(new_nodes, false);
- }
- size_type i;
- BOOST_TRY {
- for (i = 1; i <= new_nodes; ++i)
- *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
- }
- BOOST_CATCH(...) {
- for (size_type j = 1; j < i; ++j)
- this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- return this->members_.m_finish + difference_type(n);
- }
-
- void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
- {
- size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
- size_type new_num_nodes = old_num_nodes + nodes_to_add;
-
- index_pointer new_nstart;
- if (this->members_.m_map_size > 2 * new_num_nodes) {
- new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
- + (add_at_front ? nodes_to_add : 0);
- if (new_nstart < this->members_.m_start.m_node)
- std::copy(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
- else
- std::copy_backward(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1,
- new_nstart + old_num_nodes);
- }
- else {
- size_type new_map_size =
- this->members_.m_map_size + max_value(this->members_.m_map_size, nodes_to_add) + 2;
-
- index_pointer new_map = this->priv_allocate_map(new_map_size);
- new_nstart = new_map + (new_map_size - new_num_nodes) / 2
- + (add_at_front ? nodes_to_add : 0);
- std::copy(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
-
- this->members_.m_map = new_map;
- this->members_.m_map_size = new_map_size;
- }
-
- this->members_.m_start.priv_set_node(new_nstart);
- this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
- }
- /// @endcond
-};
-
-// Nonmember functions.
-template <class T, class Alloc>
-inline bool operator==(const deque<T, Alloc>& x,
- const deque<T, Alloc>& y)
-{
- return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
-}
-
-template <class T, class Alloc>
-inline bool operator<(const deque<T, Alloc>& x,
- const deque<T, Alloc>& y)
-{
- return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
-
-template <class T, class Alloc>
-inline bool operator!=(const deque<T, Alloc>& x,
- const deque<T, Alloc>& y)
- { return !(x == y); }
-
-template <class T, class Alloc>
-inline bool operator>(const deque<T, Alloc>& x,
- const deque<T, Alloc>& y)
- { return y < x; }
-
-template <class T, class Alloc>
-inline bool operator<=(const deque<T, Alloc>& x,
- const deque<T, Alloc>& y)
- { return !(y < x); }
-
-template <class T, class Alloc>
-inline bool operator>=(const deque<T, Alloc>& x,
- const deque<T, Alloc>& y)
- { return !(x < y); }
-
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class A>
-inline void swap(deque<T, A>& x, deque<T, A>& y)
-{ x.swap(y); }
-
-template <class T, class A>
-inline void swap(detail::moved_object<deque<T, A> > x, deque<T, A>& y)
-{ x.get().swap(y); }
-
-template <class T, class A>
-inline void swap(deque<T, A> &x, detail::moved_object<deque<T, A> > y)
-{ x.swap(y.get()); }
-#else
-template <class T, class A>
-inline void swap(deque<T, A>&&x, deque<T, A>&&y)
-{ x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class A>
-struct is_movable<deque<T, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class A>
-struct has_trivial_destructor_after_move<deque<T, A> >
-{
- enum { value = has_trivial_destructor<A>::value };
-};
-/// @endcond
+using boost::interprocess_container::deque;
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif // #ifndef BOOST_INTERPROCESS_DEQUE_HPP
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_DEQUE_HPP
Deleted: trunk/boost/interprocess/containers/detail/flat_tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/flat_tree.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,887 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-////////////////////////////////////////////////////////////////////////////////
-// The Loki Library
-// Copyright (c) 2001 by Andrei Alexandrescu
-// This code accompanies the book:
-// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
-// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
-// permission notice appear in supporting documentation.
-// The author or Addison-Welsey Longman make no representations about the
-// suitability of this software for any purpose. It is provided "as is"
-// without express or implied warranty.
-///////////////////////////////////////////////////////////////////////////////
-//
-// Parts of this file come from AssocVector.h file from Loki library
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_FLAT_TREE_HPP
-#define BOOST_INTERPROCESS_FLAT_TREE_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/containers/vector.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <algorithm>
-#include <functional>
-#include <utility>
-
-namespace boost {
-
-namespace interprocess {
-
-namespace detail {
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-class flat_tree
-{
- typedef boost::interprocess::vector<Value, Alloc> vector_t;
- typedef Alloc allocator_t;
-
- public:
- class value_compare
- : private Compare
- {
- typedef Value first_argument_type;
- typedef Value second_argument_type;
- typedef bool return_type;
- public:
- value_compare(const Compare &pred)
- : Compare(pred)
- {}
-
- bool operator()(const Value& lhs, const Value& rhs) const
- {
- KeyOfValue key_extract;
- return Compare::operator()(key_extract(lhs), key_extract(rhs));
- }
-
- const Compare &get_comp() const
- { return *this; }
-
- Compare &get_comp()
- { return *this; }
- };
-
- private:
- struct Data
- //Inherit from value_compare to do EBO
- : public value_compare
- {
- public:
- Data(const Compare &comp,
- const vector_t &vect)
- : value_compare(comp), m_vect(vect){}
-
- Data(const value_compare &comp,
- const vector_t &vect)
- : value_compare(comp), m_vect(vect){}
-
- Data(const Compare &comp,
- const allocator_t &alloc)
- : value_compare(comp), m_vect(alloc){}
- public:
- vector_t m_vect;
- };
-
- Data m_data;
-
- public:
-
- typedef typename vector_t::value_type value_type;
- typedef typename vector_t::pointer pointer;
- typedef typename vector_t::const_pointer const_pointer;
- typedef typename vector_t::reference reference;
- typedef typename vector_t::const_reference const_reference;
- typedef Key key_type;
- typedef Compare key_compare;
- typedef typename vector_t::allocator_type allocator_type;
- typedef allocator_type stored_allocator_type;
- typedef typename allocator_type::size_type size_type;
- typedef typename allocator_type::difference_type difference_type;
- typedef typename vector_t::iterator iterator;
- typedef typename vector_t::const_iterator const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-
- // allocation/deallocation
- flat_tree(const Compare& comp = Compare(),
- const allocator_type& a = allocator_type())
- : m_data(comp, a)
- { }
-
- flat_tree(const flat_tree& x)
- : m_data(x.m_data, x.m_data.m_vect)
- { }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_tree(detail::moved_object<flat_tree> x)
- : m_data(detail::move_impl(x.get().m_data))
- { }
- #else
- flat_tree(flat_tree &&x)
- : m_data(detail::move_impl(x.m_data))
- { }
- #endif
-
- ~flat_tree()
- { }
-
- flat_tree& operator=(const flat_tree& x)
- { m_data = x.m_data; return *this; }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_tree& operator=(detail::moved_object<flat_tree> mx)
- { m_data = detail::move_impl(mx.get().m_data); return *this; }
- #else
- flat_tree& operator=(flat_tree &&mx)
- { m_data = detail::move_impl(mx.m_data); return *this; }
- #endif
-
- public:
- // accessors:
- Compare key_comp() const
- { return this->m_data.get_comp(); }
-
- allocator_type get_allocator() const
- { return this->m_data.m_vect.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return this->m_data.m_vect.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return this->m_data.m_vect.get_stored_allocator(); }
-
- iterator begin()
- { return this->m_data.m_vect.begin(); }
-
- const_iterator begin() const
- { return this->cbegin(); }
-
- const_iterator cbegin() const
- { return this->m_data.m_vect.begin(); }
-
- iterator end()
- { return this->m_data.m_vect.end(); }
-
- const_iterator end() const
- { return this->cend(); }
-
- const_iterator cend() const
- { return this->m_data.m_vect.end(); }
-
- reverse_iterator rbegin()
- { return reverse_iterator(this->end()); }
-
- const_reverse_iterator rbegin() const
- { return this->crbegin(); }
-
- const_reverse_iterator crbegin() const
- { return const_reverse_iterator(this->cend()); }
-
- reverse_iterator rend()
- { return reverse_iterator(this->begin()); }
-
- const_reverse_iterator rend() const
- { return this->crend(); }
-
- const_reverse_iterator crend() const
- { return const_reverse_iterator(this->cbegin()); }
-
- bool empty() const
- { return this->m_data.m_vect.empty(); }
-
- size_type size() const
- { return this->m_data.m_vect.size(); }
-
- size_type max_size() const
- { return this->m_data.m_vect.max_size(); }
-
- void swap(flat_tree& other)
- {
- value_compare& mycomp = this->m_data;
- value_compare& othercomp = other.m_data;
- detail::do_swap(mycomp, othercomp);
- vector_t & myvect = this->m_data.m_vect;
- vector_t & othervect = other.m_data.m_vect;
- myvect.swap(othervect);
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(detail::moved_object<flat_tree> other)
- { this->swap(other.get()); }
- #else
- void swap(flat_tree &&other)
- { this->swap(other); }
- #endif
-
- public:
- // insert/erase
- std::pair<iterator,bool> insert_unique(const value_type& val)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, val);
- }
- return ret;
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert_unique(detail::moved_object<value_type> mval)
- {
- value_type &val = mval.get();
- #else
- std::pair<iterator,bool> insert_unique(value_type && val)
- {
- #endif
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl(val));
- }
- return ret;
- }
-
-
- iterator insert_equal(const value_type& val)
- {
- iterator i = this->upper_bound(KeyOfValue()(val));
- i = this->m_data.m_vect.insert(i, val);
- return i;
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_equal(detail::moved_object<value_type> mval)
- {
- iterator i = this->upper_bound(KeyOfValue()(mval.get()));
- i = this->m_data.m_vect.insert(i, mval);
- return i;
- }
- #else
- iterator insert_equal(value_type && mval)
- {
- iterator i = this->upper_bound(KeyOfValue()(mval));
- i = this->m_data.m_vect.insert(i, detail::move_impl(mval));
- return i;
- }
- #endif
-
- iterator insert_unique(const_iterator pos, const value_type& val)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, val);
- }
- return ret.first;
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_unique(const_iterator pos, detail::moved_object<value_type> mval)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval.get(), data);
- if(ret.second){
- ret.first = priv_insert_commit(data, mval);
- }
- return ret.first;
- }
- #else
- iterator insert_unique(const_iterator pos, value_type&&mval)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl(mval));
- }
- return ret.first;
- }
- #endif
-
- iterator insert_equal(const_iterator pos, const value_type& val)
- {
- insert_commit_data data;
- priv_insert_equal_prepare(pos, val, data);
- return priv_insert_commit(data, val);
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_equal(const_iterator pos, detail::moved_object<value_type> mval)
- {
- insert_commit_data data;
- priv_insert_equal_prepare(pos, mval.get(), data);
- return priv_insert_commit(data, mval);
- }
- #else
- iterator insert_equal(const_iterator pos, value_type && mval)
- {
- insert_commit_data data;
- priv_insert_equal_prepare(pos, mval, data);
- return priv_insert_commit(data, detail::move_impl(mval));
- }
- #endif
-
- template <class InIt>
- void insert_unique(InIt first, InIt last)
- {
- for ( ; first != last; ++first)
- this->insert_unique(*first);
- }
-
- template <class InIt>
- void insert_equal(InIt first, InIt last)
- {
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- priv_insert_equal(first, last, ItCat());
- }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template <class... Args>
- iterator emplace_unique(Args&&... args)
- {
- value_type val(detail::forward_impl<Args>(args)...);
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- priv_insert_unique_prepare(val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
- }
- return ret.first;
- }
-
- template <class... Args>
- iterator emplace_hint_unique(const_iterator hint, Args&&... args)
- {
- value_type val(detail::forward_impl<Args>(args)...);
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
- }
- return ret.first;
- }
-
- template <class... Args>
- iterator emplace_equal(Args&&... args)
- {
- value_type val(detail::forward_impl<Args>(args)...);
- iterator i = this->upper_bound(KeyOfValue()(val));
- i = this->m_data.m_vect.insert(i, detail::move_impl<value_type>(val));
- return i;
- }
-
- template <class... Args>
- iterator emplace_hint_equal(const_iterator hint, Args&&... args)
- {
- value_type val(detail::forward_impl<Args>(args)...);
- insert_commit_data data;
- priv_insert_equal_prepare(hint, val, data);
- return priv_insert_commit(data, detail::move_impl<value_type>(val));
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace_unique()
- {
- detail::value_init<value_type> vval;
- value_type &val = vval.m_t;
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- priv_insert_unique_prepare(val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
- }
- return ret.first;
- }
-
- iterator emplace_hint_unique(const_iterator hint)
- {
- detail::value_init<value_type> vval;
- value_type &val = vval.m_t;
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
- if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
- }
- return ret.first;
- }
-
- iterator emplace_equal()
- {
- detail::value_init<value_type> vval;
- value_type &val = vval.m_t;
- iterator i = this->upper_bound(KeyOfValue()(val));
- i = this->m_data.m_vect.insert(i, detail::move_impl<value_type>(val));
- return i;
- }
-
- iterator emplace_hint_equal(const_iterator hint)
- {
- detail::value_init<value_type> vval;
- value_type &val = vval.m_t;
- insert_commit_data data;
- priv_insert_equal_prepare(hint, val, data);
- return priv_insert_commit(data, detail::move_impl<value_type>(val));
- }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- insert_commit_data data; \
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
- if(ret.second){ \
- ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val)); \
- } \
- return ret.first; \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint_unique(const_iterator hint, \
- BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- insert_commit_data data; \
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
- if(ret.second){ \
- ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val)); \
- } \
- return ret.first; \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- iterator i = this->upper_bound(KeyOfValue()(val)); \
- i = this->m_data.m_vect.insert(i, detail::move_impl<value_type>(val)); \
- return i; \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint_equal(const_iterator hint, \
- BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- insert_commit_data data; \
- priv_insert_equal_prepare(hint, val, data); \
- return priv_insert_commit(data, detail::move_impl<value_type>(val)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator erase(const_iterator position)
- { return this->m_data.m_vect.erase(position); }
-
- size_type erase(const key_type& k)
- {
- std::pair<iterator,iterator > itp = this->equal_range(k);
- size_type ret = static_cast<size_type>(itp.second-itp.first);
- if (ret){
- this->m_data.m_vect.erase(itp.first, itp.second);
- }
- return ret;
- }
-
- iterator erase(const_iterator first, const_iterator last)
- { return this->m_data.m_vect.erase(first, last); }
-
- void clear()
- { this->m_data.m_vect.clear(); }
-
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- // with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { this->m_data.m_vect.shrink_to_fit(); }
-
- // set operations:
- iterator find(const key_type& k)
- {
- const Compare &key_comp = this->m_data.get_comp();
- iterator i = this->lower_bound(k);
-
- if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
- i = this->end();
- }
- return i;
- }
-
- const_iterator find(const key_type& k) const
- {
- const Compare &key_comp = this->m_data.get_comp();
- const_iterator i = this->lower_bound(k);
-
- if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
- i = this->end();
- }
- return i;
- }
-
- size_type count(const key_type& k) const
- {
- std::pair<const_iterator, const_iterator> p = this->equal_range(k);
- size_type n = p.second - p.first;
- return n;
- }
-
- iterator lower_bound(const key_type& k)
- { return this->priv_lower_bound(this->begin(), this->end(), k); }
-
- const_iterator lower_bound(const key_type& k) const
- { return this->priv_lower_bound(this->begin(), this->end(), k); }
-
- iterator upper_bound(const key_type& k)
- { return this->priv_upper_bound(this->begin(), this->end(), k); }
-
- const_iterator upper_bound(const key_type& k) const
- { return this->priv_upper_bound(this->begin(), this->end(), k); }
-
- std::pair<iterator,iterator> equal_range(const key_type& k)
- { return this->priv_equal_range(this->begin(), this->end(), k); }
-
- std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
- { return this->priv_equal_range(this->begin(), this->end(), k); }
-
- size_type capacity() const
- { return this->m_data.m_vect.capacity(); }
-
- void reserve(size_type count)
- { this->m_data.m_vect.reserve(count); }
-
- private:
- struct insert_commit_data
- {
- const_iterator position;
- };
-
- // insert/erase
- void priv_insert_equal_prepare
- (const_iterator pos, const value_type& val, insert_commit_data &data)
- {
- // N1780
- // To insert val at pos:
- // if pos == end || val <= *pos
- // if pos == begin || val >= *(pos-1)
- // insert val before pos
- // else
- // insert val before upper_bound(val)
- // else if pos+1 == end || val <= *(pos+1)
- // insert val after pos
- // else
- // insert val before lower_bound(val)
- const value_compare &value_comp = this->m_data;
-
- if(pos == this->cend() || !value_comp(*pos, val)){
- if (pos == this->cbegin() || !value_comp(val, pos[-1])){
- data.position = pos;
- }
- else{
- data.position =
- this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
- }
- }
- //Works, but increases code complexity
- //else if (++pos == this->end() || !value_comp(*pos, val)){
- // return this->m_data.m_vect.insert(pos, val);
- //}
- else{
- data.position =
- this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
- }
- }
-
- std::pair<iterator,bool> priv_insert_unique_prepare
- (const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
- {
- const value_compare &value_comp = this->m_data;
- commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
- return std::pair<iterator,bool>
- ( *reinterpret_cast<iterator*>(&commit_data.position)
- , commit_data.position == end || value_comp(val, *commit_data.position));
- }
-
- std::pair<iterator,bool> priv_insert_unique_prepare
- (const value_type& val, insert_commit_data &commit_data)
- { return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
-
- std::pair<iterator,bool> priv_insert_unique_prepare
- (const_iterator pos, const value_type& val, insert_commit_data &commit_data)
- {
- //N1780. Props to Howard Hinnant!
- //To insert val at pos:
- //if pos == end || val <= *pos
- // if pos == begin || val >= *(pos-1)
- // insert val before pos
- // else
- // insert val before upper_bound(val)
- //else if pos+1 == end || val <= *(pos+1)
- // insert val after pos
- //else
- // insert val before lower_bound(val)
- const value_compare &value_comp = this->m_data;
-
- if(pos == this->cend() || value_comp(val, *pos)){
- if(pos != this->cbegin() && !value_comp(val, pos[-1])){
- if(value_comp(pos[-1], val)){
- commit_data.position = pos;
- return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
- }
- else{
- return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
- }
- }
- return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
- }
-
- // Works, but increases code complexity
- //Next check
- //else if (value_comp(*pos, val) && !value_comp(pos[1], val)){
- // if(value_comp(val, pos[1])){
- // commit_data.position = pos+1;
- // return std::pair<iterator,bool>(pos+1, true);
- // }
- // else{
- // return std::pair<iterator,bool>(pos+1, false);
- // }
- //}
- else{
- //[... pos ... val ... ]
- //The hint is before the insertion position, so insert it
- //in the remaining range
- return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data);
- }
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible>
- iterator priv_insert_commit
- (insert_commit_data &commit_data, const Convertible &convertible)
- { return this->m_data.m_vect.insert(commit_data.position, convertible); }
- #else
- template<class Convertible>
- iterator priv_insert_commit
- (insert_commit_data &commit_data, Convertible &&convertible)
- { return this->m_data.m_vect.insert(commit_data.position, detail::forward_impl<Convertible>(convertible)); }
- #endif
-
- template <class RanIt>
- RanIt priv_lower_bound(RanIt first, RanIt last,
- const key_type & key) const
- {
- const Compare &key_comp = this->m_data.get_comp();
- KeyOfValue key_extract;
- difference_type len = last - first, half;
- RanIt middle;
-
- while (len > 0) {
- half = len >> 1;
- middle = first;
- middle += half;
-
- if (key_comp(key_extract(*middle), key)) {
- ++middle;
- first = middle;
- len = len - half - 1;
- }
- else
- len = half;
- }
- return first;
- }
-
- template <class RanIt>
- RanIt priv_upper_bound(RanIt first, RanIt last,
- const key_type & key) const
- {
- const Compare &key_comp = this->m_data.get_comp();
- KeyOfValue key_extract;
- difference_type len = last - first, half;
- RanIt middle;
-
- while (len > 0) {
- half = len >> 1;
- middle = first;
- middle += half;
-
- if (key_comp(key, key_extract(*middle))) {
- len = half;
- }
- else{
- first = ++middle;
- len = len - half - 1;
- }
- }
- return first;
- }
-
- template <class RanIt>
- std::pair<RanIt, RanIt>
- priv_equal_range(RanIt first, RanIt last, const key_type& key) const
- {
- const Compare &key_comp = this->m_data.get_comp();
- KeyOfValue key_extract;
- difference_type len = last - first, half;
- RanIt middle, left, right;
-
- while (len > 0) {
- half = len >> 1;
- middle = first;
- middle += half;
-
- if (key_comp(key_extract(*middle), key)){
- first = middle;
- ++first;
- len = len - half - 1;
- }
- else if (key_comp(key, key_extract(*middle))){
- len = half;
- }
- else {
- left = this->priv_lower_bound(first, middle, key);
- first += len;
- right = this->priv_upper_bound(++middle, first, key);
- return std::pair<RanIt, RanIt>(left, right);
- }
- }
- return std::pair<RanIt, RanIt>(first, first);
- }
-
- template <class FwdIt>
- void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- size_type len = static_cast<size_type>(std::distance(first, last));
- this->reserve(this->size()+len);
- this->priv_insert_equal(first, last, std::input_iterator_tag());
- }
-
- template <class InIt>
- void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
- {
- for ( ; first != last; ++first)
- this->insert_equal(*first);
- }
-
-/*
- template <class FwdIt>
- void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- size_type len = static_cast<size_type>(std::distance(first, last));
- this->reserve(this->size()+len);
- priv_insert_unique(first, last, std::input_iterator_tag());
- }
-
- template <class InIt>
- void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag)
- {
- for ( ; first != last; ++first)
- this->insert_unique(*first);
- }
-*/
-};
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator==(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
-{
- return x.size() == y.size() &&
- std::equal(x.begin(), x.end(), y.begin());
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator<(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
-{
- return std::lexicographical_compare(x.begin(), x.end(),
- y.begin(), y.end());
-}
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
- { return !(x == y); }
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator>(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
- { return y < x; }
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
- { return !(y < x); }
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline bool
-operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
- { return !(x < y); }
-
-
-template <class Key, class Value, class KeyOfValue,
- class Compare, class Alloc>
-inline void
-swap(flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
- flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
- { x.swap(y); }
-
-} //namespace detail {
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class K, class V, class KOV,
- class C, class A>
-struct has_trivial_destructor_after_move<detail::flat_tree<K, V, KOV, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-
-} //namespace interprocess {
-
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif // BOOST_INTERPROCESS_FLAT_TREE_HPP
Deleted: trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,428 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_
-#define BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
-#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/intrusive/options.hpp>
-
-#include <utility>
-#include <functional>
-
-
-namespace boost {
-namespace interprocess {
-namespace detail {
-
-template<class ValueCompare, class Node>
-struct node_compare
- : private ValueCompare
-{
- typedef typename ValueCompare::key_type key_type;
- typedef typename ValueCompare::value_type value_type;
- typedef typename ValueCompare::key_of_value key_of_value;
-
- node_compare(const ValueCompare &pred)
- : ValueCompare(pred)
- {}
-
- ValueCompare &value_comp()
- { return static_cast<ValueCompare &>(*this); }
-
- ValueCompare &value_comp() const
- { return static_cast<const ValueCompare &>(*this); }
-
- bool operator()(const Node &a, const Node &b) const
- { return ValueCompare::operator()(a.get_data(), b.get_data()); }
-};
-
-template<class A, class ICont>
-struct node_alloc_holder
-{
- typedef node_alloc_holder<A, ICont> self_t;
- typedef typename A::value_type value_type;
- typedef typename ICont::value_type Node;
- typedef typename A::template rebind<Node>::other NodeAlloc;
- typedef A ValAlloc;
- typedef typename NodeAlloc::pointer NodePtr;
- typedef detail::scoped_deallocator<NodeAlloc> Deallocator;
- typedef typename NodeAlloc::size_type size_type;
- typedef typename NodeAlloc::difference_type difference_type;
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
- typedef detail::integral_constant<unsigned,
- boost::interprocess::detail::
- version<NodeAlloc>::value> alloc_version;
- typedef typename ICont::iterator icont_iterator;
- typedef typename ICont::const_iterator icont_citerator;
- typedef allocator_destroyer<NodeAlloc> Destroyer;
-
- node_alloc_holder(const ValAlloc &a)
- : members_(a)
- {}
-
- node_alloc_holder(const node_alloc_holder &other)
- : members_(other.node_alloc())
- {}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- node_alloc_holder(detail::moved_object<node_alloc_holder> other)
- : members_(detail::move_impl(other.get().node_alloc()))
- { this->swap(other.get()); }
- #else
- node_alloc_holder(node_alloc_holder &&other)
- : members_(detail::move_impl(other.node_alloc()))
- { this->swap(other); }
- #endif
-
- template<class Pred>
- node_alloc_holder(const ValAlloc &a, const Pred &c)
- : members_(a, typename ICont::value_compare(c))
- {}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Pred>
- node_alloc_holder(detail::moved_object<ValAlloc> a, const Pred &c)
- : members_(a.get(), typename ICont::value_compare(c))
- {}
- #else
- template<class Pred>
- node_alloc_holder(ValAlloc &&a, const Pred &c)
- : members_(a, typename ICont::value_compare(c))
- {}
- #endif
-
- template<class Pred>
- node_alloc_holder(const node_alloc_holder &other, const Pred &c)
- : members_(other.node_alloc(), typename ICont::value_compare(c))
- {}
-
- ~node_alloc_holder()
- { this->clear(alloc_version()); }
-
- size_type max_size() const
- { return this->node_alloc().max_size(); }
-
- NodePtr allocate_one()
- { return this->allocate_one(alloc_version()); }
-
- NodePtr allocate_one(allocator_v1)
- { return this->node_alloc().allocate(1); }
-
- NodePtr allocate_one(allocator_v2)
- { return this->node_alloc().allocate_one(); }
-
- void deallocate_one(NodePtr p)
- { return this->deallocate_one(p, alloc_version()); }
-
- void deallocate_one(NodePtr p, allocator_v1)
- { this->node_alloc().deallocate(p, 1); }
-
- void deallocate_one(NodePtr p, allocator_v2)
- { this->node_alloc().deallocate_one(p); }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible1, class Convertible2>
- static void construct(const NodePtr &ptr, detail::moved_object<std::pair<Convertible1, Convertible2> > value)
- {
- typedef typename Node::hook_type hook_type;
- typedef typename Node::value_type::first_type first_type;
- typedef typename Node::value_type::second_type second_type;
- Node *nodeptr = detail::get_pointer(ptr);
-
- //Hook constructor does not throw
- new(static_cast<hook_type*>(nodeptr))hook_type();
- //Now construct pair members_holder
- value_type *valueptr = &nodeptr->get_data();
- new((void*)&valueptr->first) first_type(detail::move_impl(value.get().first));
- BOOST_TRY{
- new((void*)&valueptr->second) second_type(detail::move_impl(value.get().second));
- }
- BOOST_CATCH(...){
- valueptr->first.~first_type();
- static_cast<hook_type*>(nodeptr)->~hook_type();
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- #else
- template<class Convertible1, class Convertible2>
- static void construct(const NodePtr &ptr, std::pair<Convertible1, Convertible2> &&value)
- {
- typedef typename Node::hook_type hook_type;
- typedef typename Node::value_type::first_type first_type;
- typedef typename Node::value_type::second_type second_type;
- Node *nodeptr = detail::get_pointer(ptr);
-
- //Hook constructor does not throw
- new(static_cast<hook_type*>(nodeptr))hook_type();
- //Now construct pair members_holder
- value_type *valueptr = &nodeptr->get_data();
- new((void*)&valueptr->first) first_type(detail::move_impl(value.first));
- BOOST_TRY{
- new((void*)&valueptr->second) second_type(detail::move_impl(value.second));
- }
- BOOST_CATCH(...){
- valueptr->first.~first_type();
- static_cast<hook_type*>(nodeptr)->~hook_type();
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- #endif
-
- static void destroy(const NodePtr &ptr)
- { detail::get_pointer(ptr)->~Node(); }
-
-
- #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- Deallocator
- #else
- move_return<Deallocator>
- #endif
- create_node_and_deallocator()
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- return node_deallocator;
- }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template<class ...Args>
- static void construct(const NodePtr &ptr, Args &&...args)
- { new((void*)detail::get_pointer(ptr)) Node(detail::forward_impl<Args>(args)...); }
-
- template<class ...Args>
- NodePtr create_node(Args &&...args)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- self_t::construct(p, detail::forward_impl<Args>(args)...);
- node_deallocator.release();
- return (p);
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- static void construct(const NodePtr &ptr)
- { new((void*)detail::get_pointer(ptr)) Node(); }
-
- NodePtr create_node()
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- self_t::construct(p);
- node_deallocator.release();
- return (p);
- }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- new((void*)detail::get_pointer(ptr)) \
- Node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- NodePtr create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- NodePtr p = this->allocate_one(); \
- Deallocator node_deallocator(p, this->node_alloc()); \
- self_t::construct(p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- node_deallocator.release(); \
- return (p); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template<class It>
- NodePtr create_node_from_it(It it)
- {
- NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, this->node_alloc());
- ::boost::interprocess::construct_in_place(detail::get_pointer(p), it);
- node_deallocator.release();
- return (p);
- }
-
- void destroy_node(NodePtr node)
- {
- self_t::destroy(node);
- this->deallocate_one(node);
- }
-
- void swap(node_alloc_holder &x)
- {
- NodeAlloc& this_alloc = this->node_alloc();
- NodeAlloc& other_alloc = x.node_alloc();
-
- if (this_alloc != other_alloc){
- detail::do_swap(this_alloc, other_alloc);
- }
-
- this->icont().swap(x.icont());
- }
-
- template<class FwdIterator, class Inserter>
- FwdIterator allocate_many_and_construct
- (FwdIterator beg, difference_type n, Inserter inserter)
- {
- if(n){
- typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
-
- //Try to allocate memory in a single block
- multiallocation_iterator itbeg =
- this->node_alloc().allocate_individual(n), itend, itold;
- int constructed = 0;
- Node *p = 0;
- BOOST_TRY{
- for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
- p = &*itbeg;
- ++itbeg;
- //This can throw
- boost::interprocess::construct_in_place(p, beg);
- ++constructed;
- //This can throw in some containers (predicate might throw)
- inserter(*p);
- }
- }
- BOOST_CATCH(...){
- if(constructed){
- this->destroy(p);
- }
- this->node_alloc().deallocate_many(itbeg);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- return beg;
-
- }
-
- void clear(allocator_v1)
- { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
-
- void clear(allocator_v2)
- {
- allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
- this->icont().clear_and_dispose(chain_holder.get_chain_builder());
- }
-
- icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
- { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
-
- icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
- {
- allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
- return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
- }
-
- template<class Key, class Comparator>
- size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
- { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
-
- template<class Key, class Comparator>
- size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
- {
- allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
- return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
- }
-
- protected:
- struct cloner
- {
- cloner(node_alloc_holder &holder)
- : m_holder(holder)
- {}
-
- NodePtr operator()(const Node &other) const
- { return m_holder.create_node(other.get_data()); }
-
- node_alloc_holder &m_holder;
- };
-
- struct destroyer
- {
- destroyer(node_alloc_holder &holder)
- : m_holder(holder)
- {}
-
- void operator()(NodePtr n) const
- { m_holder.destroy_node(n); }
-
- node_alloc_holder &m_holder;
- };
-
- struct members_holder
- : public NodeAlloc
- {
- private:
- members_holder(const members_holder&);
-
- public:
- template<class ConvertibleToAlloc>
- members_holder(const ConvertibleToAlloc &c2alloc)
- : NodeAlloc(c2alloc)
- {}
-
- template<class ConvertibleToAlloc, class Pred>
- members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
- : NodeAlloc(c2alloc), m_icont(c)
- {}
- //The intrusive container
- ICont m_icont;
- } members_;
-
- ICont &non_const_icont() const
- { return const_cast<ICont&>(this->members_.m_icont); }
-
- ICont &icont()
- { return this->members_.m_icont; }
-
- const ICont &icont() const
- { return this->members_.m_icont; }
-
- NodeAlloc &node_alloc()
- { return static_cast<NodeAlloc &>(this->members_); }
-
- const NodeAlloc &node_alloc() const
- { return static_cast<const NodeAlloc &>(this->members_); }
-};
-
-} //namespace detail {
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif // BOOST_INTERPROCESS_DETAIL_NODE_ALLOC_HPP_
Deleted: trunk/boost/interprocess/containers/detail/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/tree.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,1111 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_tree file. Modified by Ion Gaztanaga 2005.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-/*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef BOOST_INTERPROCESS_TREE_HPP
-#define BOOST_INTERPROCESS_TREE_HPP
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
-#include <boost/intrusive/rbtree.hpp>
-#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-#include <boost/interprocess/detail/preprocessor.hpp>
-#endif
-
-#include <utility> //std::pair
-#include <iterator>
-#include <algorithm>
-
-namespace boost {
-namespace interprocess {
-namespace detail {
-
-template<class Key, class Value, class KeyCompare, class KeyOfValue>
-struct value_compare_impl
- : public KeyCompare
-{
- typedef Value value_type;
- typedef KeyCompare key_compare;
- typedef KeyOfValue key_of_value;
- typedef Key key_type;
-
- value_compare_impl(key_compare kcomp)
- : key_compare(kcomp)
- {}
-
- const key_compare &key_comp() const
- { return static_cast<const key_compare &>(*this); }
-
- key_compare &key_comp()
- { return static_cast<key_compare &>(*this); }
-
- template<class A, class B>
- bool operator()(const A &a, const B &b) const
- { return key_compare::operator()(KeyOfValue()(a), KeyOfValue()(b)); }
-};
-
-template<class VoidPointer>
-struct rbtree_hook
-{
- typedef typename bi::make_set_base_hook
- < bi::void_pointer<VoidPointer>
- , bi::link_mode<bi::normal_link>
- , bi::optimize_size<true>
- >::type type;
-};
-
-template<class T>
-struct rbtree_type
-{
- typedef T type;
-};
-
-template<class T1, class T2>
-struct rbtree_type< std::pair<T1, T2> >
-{
- typedef detail::pair<T1, T2> type;
-};
-
-template <class T, class VoidPointer>
-struct rbtree_node
- : public rbtree_hook<VoidPointer>::type
-{
- typedef typename rbtree_hook<VoidPointer>::type hook_type;
-
- typedef T value_type;
- typedef typename rbtree_type<T>::type internal_type;
-
- typedef rbtree_node<T, VoidPointer> node_type;
-
- #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- rbtree_node()
- : m_data()
- {}
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- rbtree_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #else //#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template<class ...Args>
- rbtree_node(Args &&...args)
- : m_data(detail::forward_impl<Args>(args)...)
- {}
- #endif//#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- rbtree_node &operator=(const rbtree_node &other)
- { do_assign(other.m_data); return *this; }
-
- T &get_data()
- {
- T* ptr = reinterpret_cast<T*>(&this->m_data);
- return *ptr;
- }
-
- const T &get_data() const
- {
- const T* ptr = reinterpret_cast<const T*>(&this->m_data);
- return *ptr;
- }
-
- private:
- internal_type m_data;
-
- template<class A, class B>
- void do_assign(const std::pair<const A, B> &p)
- {
- const_cast<A&>(m_data.first) = p.first;
- m_data.second = p.second;
- }
-
- template<class A, class B>
- void do_assign(const detail::pair<const A, B> &p)
- {
- const_cast<A&>(m_data.first) = p.first;
- m_data.second = p.second;
- }
-
- template<class V>
- void do_assign(const V &v)
- { m_data = v; }
-
- public:
- template<class Convertible>
-
- static void construct(node_type *ptr
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE)
- , const Convertible &value)
- #else
- , Convertible &&value)
- #endif
- { new(ptr) node_type(detail::forward_impl<Convertible>(value)); }
-};
-
-}//namespace detail {
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) || !defined(BOOST_INTERPROCESS_RVALUE_PAIR)
-template<class T, class VoidPointer>
-struct has_own_construct_from_it
- < boost::interprocess::detail::rbtree_node<T, VoidPointer> >
-{
- static const bool value = true;
-};
-#endif
-namespace detail {
-
-template<class A, class ValueCompare>
-struct intrusive_rbtree_type
-{
- typedef typename A::value_type value_type;
- typedef typename detail::pointer_to_other
- <typename A::pointer, void>::type void_pointer;
- typedef typename detail::rbtree_node
- <value_type, void_pointer> node_type;
- typedef node_compare<ValueCompare, node_type> node_compare_type;
- typedef typename bi::make_rbtree
- <node_type
- ,bi::compare<node_compare_type>
- ,bi::base_hook<typename rbtree_hook<void_pointer>::type>
- ,bi::constant_time_size<true>
- ,bi::size_type<typename A::size_type>
- >::type container_type;
- typedef container_type type ;
-};
-
-} //namespace detail {
-
-namespace detail {
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-class rbtree
- : protected detail::node_alloc_holder
- <A, typename detail::intrusive_rbtree_type
- <A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue>
- >::type
- >
-{
- typedef typename detail::intrusive_rbtree_type
- <A, value_compare_impl
- <Key, Value, KeyCompare, KeyOfValue>
- >::type Icont;
- typedef detail::node_alloc_holder<A, Icont> AllocHolder;
- typedef typename AllocHolder::NodePtr NodePtr;
- typedef rbtree < Key, Value, KeyOfValue
- , KeyCompare, A> ThisType;
- typedef typename AllocHolder::NodeAlloc NodeAlloc;
- typedef typename AllocHolder::ValAlloc ValAlloc;
- typedef typename AllocHolder::Node Node;
- typedef typename Icont::iterator iiterator;
- typedef typename Icont::const_iterator iconst_iterator;
- typedef detail::allocator_destroyer<NodeAlloc> Destroyer;
- typedef typename AllocHolder::allocator_v1 allocator_v1;
- typedef typename AllocHolder::allocator_v2 allocator_v2;
- typedef typename AllocHolder::alloc_version alloc_version;
-
- class RecyclingCloner;
- friend class RecyclingCloner;
-
- class RecyclingCloner
- {
- public:
- RecyclingCloner(AllocHolder &holder, Icont &irbtree)
- : m_holder(holder), m_icont(irbtree)
- {}
-
- NodePtr operator()(const Node &other) const
- {
-// if(!m_icont.empty()){
- if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
- //First recycle a node (this can't throw)
- //NodePtr p = m_icont.unlink_leftmost_without_rebalance();
- try{
- //This can throw
- *p = other;
- return p;
- }
- catch(...){
- //If there is an exception destroy the whole source
- m_holder.destroy_node(p);
- while((p = m_icont.unlink_leftmost_without_rebalance())){
- m_holder.destroy_node(p);
- }
- throw;
- }
- }
- else{
- return m_holder.create_node(other);
- }
- }
-
- AllocHolder &m_holder;
- Icont &m_icont;
- };
-
- public:
- typedef Key key_type;
- typedef Value value_type;
- typedef A allocator_type;
- typedef KeyCompare key_compare;
- typedef value_compare_impl< Key, Value
- , KeyCompare, KeyOfValue> value_compare;
- typedef typename A::pointer pointer;
- typedef typename A::const_pointer const_pointer;
- typedef typename A::reference reference;
- typedef typename A::const_reference const_reference;
- typedef typename A::size_type size_type;
- typedef typename A::difference_type difference_type;
- typedef difference_type rbtree_difference_type;
- typedef pointer rbtree_pointer;
- typedef const_pointer rbtree_const_pointer;
- typedef reference rbtree_reference;
- typedef const_reference rbtree_const_reference;
- typedef NodeAlloc stored_allocator_type;
-
- private:
-
- template<class KeyValueCompare>
- struct key_node_compare
- : private KeyValueCompare
- {
- key_node_compare(KeyValueCompare comp)
- : KeyValueCompare(comp)
- {}
-
- template<class KeyType>
- bool operator()(const Node &n, const KeyType &k) const
- { return KeyValueCompare::operator()(n.get_data(), k); }
-
- template<class KeyType>
- bool operator()(const KeyType &k, const Node &n) const
- { return KeyValueCompare::operator()(k, n.get_data()); }
- };
-
- typedef key_node_compare<value_compare> KeyNodeCompare;
-
- public:
- //rbtree const_iterator
- class const_iterator
- : public std::iterator
- < std::bidirectional_iterator_tag
- , value_type , rbtree_difference_type
- , rbtree_const_pointer , rbtree_const_reference>
- {
- protected:
- typedef typename Icont::iterator iiterator;
- iiterator m_it;
- explicit const_iterator(iiterator it) : m_it(it){}
- void prot_incr() { ++m_it; }
- void prot_decr() { --m_it; }
-
- private:
- iiterator get()
- { return this->m_it; }
-
- public:
- friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
- typedef rbtree_difference_type difference_type;
-
- //Constructors
- const_iterator()
- : m_it()
- {}
-
- //Pointer like operators
- const_reference operator*() const
- { return m_it->get_data(); }
-
- const_pointer operator->() const
- { return const_pointer(&m_it->get_data()); }
-
- //Increment / Decrement
- const_iterator& operator++()
- { prot_incr(); return *this; }
-
- const_iterator operator++(int)
- { iiterator tmp = m_it; ++*this; return const_iterator(tmp); }
-
- const_iterator& operator--()
- { prot_decr(); return *this; }
-
- const_iterator operator--(int)
- { iiterator tmp = m_it; --*this; return const_iterator(tmp); }
-
- //Comparison operators
- bool operator== (const const_iterator& r) const
- { return m_it == r.m_it; }
-
- bool operator!= (const const_iterator& r) const
- { return m_it != r.m_it; }
- };
-
- //rbtree iterator
- class iterator : public const_iterator
- {
- private:
- explicit iterator(iiterator it)
- : const_iterator(it)
- {}
-
- iiterator get()
- { return this->m_it; }
-
- public:
- friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
- typedef rbtree_pointer pointer;
- typedef rbtree_reference reference;
-
- //Constructors
- iterator(){}
-
- //Pointer like operators
- reference operator*() const { return this->m_it->get_data(); }
- pointer operator->() const { return pointer(&this->m_it->get_data()); }
-
- //Increment / Decrement
- iterator& operator++()
- { this->prot_incr(); return *this; }
-
- iterator operator++(int)
- { iiterator tmp = this->m_it; ++*this; return iterator(tmp); }
-
- iterator& operator--()
- { this->prot_decr(); return *this; }
-
- iterator operator--(int)
- { iterator tmp = *this; --*this; return tmp; }
- };
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- rbtree(const key_compare& comp = key_compare(),
- const allocator_type& a = allocator_type())
- : AllocHolder(a, comp)
- {}
-
- template <class InputIterator>
- rbtree(InputIterator first, InputIterator last, const key_compare& comp,
- const allocator_type& a, bool unique_insertion)
- : AllocHolder(a, comp)
- {
- typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
- }
-
- rbtree(const rbtree& x)
- : AllocHolder(x, x.key_comp())
- {
- this->icont().clone_from
- (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- rbtree(detail::moved_object<rbtree> x)
- : AllocHolder(x.get(), x.get().key_comp())
- { this->swap(x.get()); }
- #else
- rbtree(rbtree &&x)
- : AllocHolder(x, x.key_comp())
- { this->swap(x); }
- #endif
-
- ~rbtree()
- {} //AllocHolder clears the tree
-
- rbtree& operator=(const rbtree& x)
- {
- if (this != &x) {
- //Transfer all the nodes to a temporary tree
- //If anything goes wrong, all the nodes will be destroyed
- //automatically
- Icont other_tree(this->icont().value_comp());
- other_tree.swap(this->icont());
-
- //Now recreate the source tree reusing nodes stored by other_tree
- this->icont().clone_from
- (x.icont()
- , RecyclingCloner(*this, other_tree)
- //, AllocHolder::cloner(*this)
- , Destroyer(this->node_alloc()));
-
- //If there are remaining nodes, destroy them
- NodePtr p;
- while((p = other_tree.unlink_leftmost_without_rebalance())){
- AllocHolder::destroy_node(p);
- }
- }
- return *this;
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- rbtree& operator=(detail::moved_object<rbtree> mx)
- { this->clear(); this->swap(mx.get()); return *this; }
- #else
- rbtree& operator=(rbtree &&mx)
- { this->clear(); this->swap(mx); return *this; }
- #endif
-
- public:
- // accessors:
- value_compare value_comp() const
- { return this->icont().value_comp().value_comp(); }
-
- key_compare key_comp() const
- { return this->icont().value_comp().value_comp().key_comp(); }
-
- allocator_type get_allocator() const
- { return allocator_type(this->node_alloc()); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return this->node_alloc(); }
-
- stored_allocator_type &get_stored_allocator()
- { return this->node_alloc(); }
-
- iterator begin()
- { return iterator(this->icont().begin()); }
-
- const_iterator begin() const
- { return this->cbegin(); }
-
- iterator end()
- { return iterator(this->icont().end()); }
-
- const_iterator end() const
- { return this->cend(); }
-
- reverse_iterator rbegin()
- { return reverse_iterator(end()); }
-
- const_reverse_iterator rbegin() const
- { return this->crbegin(); }
-
- reverse_iterator rend()
- { return reverse_iterator(begin()); }
-
- const_reverse_iterator rend() const
- { return this->crend(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return const_iterator(this->non_const_icont().begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return const_iterator(this->non_const_icont().end()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return const_reverse_iterator(cend()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return const_reverse_iterator(cbegin()); }
-
- bool empty() const
- { return !this->size(); }
-
- size_type size() const
- { return this->icont().size(); }
-
- size_type max_size() const
- { return AllocHolder::max_size(); }
-
- void swap(ThisType& x)
- { AllocHolder::swap(x); }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(detail::moved_object<rbtree> mt)
- { this->swap(mt.get()); }
- #else
- void swap(rbtree &&mt)
- { this->swap(mt); }
- #endif
-
- public:
-
- typedef typename Icont::insert_commit_data insert_commit_data;
-
- // insert/erase
- std::pair<iterator,bool> insert_unique_check
- (const key_type& key, insert_commit_data &data)
- {
- std::pair<iiterator, bool> ret =
- this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
- return std::pair<iterator, bool>(iterator(ret.first), ret.second);
- }
-
- std::pair<iterator,bool> insert_unique_check
- (const_iterator hint, const key_type& key, insert_commit_data &data)
- {
- std::pair<iiterator, bool> ret =
- this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
- return std::pair<iterator, bool>(iterator(ret.first), ret.second);
- }
-
- iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
- {
- NodePtr tmp = AllocHolder::create_node(v);
- iiterator it(this->icont().insert_unique_commit(*tmp, data));
- return iterator(it);
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class MovableConvertible>
- iterator insert_unique_commit
- (detail::moved_object<MovableConvertible> mv, insert_commit_data &data)
- {
- NodePtr tmp = AllocHolder::create_node(mv);
- iiterator it(this->icont().insert_unique_commit(*tmp, data));
- return iterator(it);
- }
- #else
- template<class MovableConvertible>
- iterator insert_unique_commit
- (MovableConvertible && mv, insert_commit_data &data)
- {
- NodePtr tmp = AllocHolder::create_node(detail::forward_impl<MovableConvertible>(mv));
- iiterator it(this->icont().insert_unique_commit(*tmp, data));
- return iterator(it);
- }
- #endif
-
- std::pair<iterator,bool> insert_unique(const value_type& v)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(KeyOfValue()(v), data);
- if(!ret.second)
- return ret;
- return std::pair<iterator,bool>
- (this->insert_unique_commit(v, data), true);
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class MovableConvertible>
- std::pair<iterator,bool> insert_unique(detail::moved_object<MovableConvertible> mv)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(KeyOfValue()(mv.get()), data);
- if(!ret.second)
- return ret;
- return std::pair<iterator,bool>
- (this->insert_unique_commit(mv, data), true);
- }
- #else
- template<class MovableConvertible>
- std::pair<iterator,bool> insert_unique(MovableConvertible &&mv)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(KeyOfValue()(mv), data);
- if(!ret.second)
- return ret;
- return std::pair<iterator,bool>
- (this->insert_unique_commit(detail::forward_impl<MovableConvertible>(mv), data), true);
- }
- #endif
-
- private:
- iterator emplace_unique_impl(NodePtr p)
- {
- value_type &v = p->get_data();
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(KeyOfValue()(v), data);
- if(!ret.second){
- Destroyer(this->node_alloc())(p);
- return ret.first;
- }
- return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
- }
-
- iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
- {
- value_type &v = p->get_data();
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(hint, KeyOfValue()(v), data);
- if(!ret.second){
- Destroyer(this->node_alloc())(p);
- return ret.first;
- }
- return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
- }
-
- public:
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template <class... Args>
- iterator emplace_unique(Args&&... args)
- { return this->emplace_unique_impl(AllocHolder::create_node(detail::forward_impl<Args>(args)...)); }
-
- template <class... Args>
- iterator emplace_hint_unique(const_iterator hint, Args&&... args)
- { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(detail::forward_impl<Args>(args)...)); }
-
- template <class... Args>
- iterator emplace_equal(Args&&... args)
- {
- NodePtr p(AllocHolder::create_node(detail::forward_impl<Args>(args)...));
- return iterator(this->icont().insert_equal(this->icont().end(), *p));
- }
-
- template <class... Args>
- iterator emplace_hint_equal(const_iterator hint, Args&&... args)
- {
- NodePtr p(AllocHolder::create_node(detail::forward_impl<Args>(args)...));
- return iterator(this->icont().insert_equal(hint.get(), *p));
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace_unique()
- { return this->emplace_unique_impl(AllocHolder::create_node()); }
-
- iterator emplace_hint_unique(const_iterator hint)
- { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node()); }
-
- iterator emplace_equal()
- {
- NodePtr p(AllocHolder::create_node());
- return iterator(this->icont().insert_equal(this->icont().end(), *p));
- }
-
- iterator emplace_hint_equal(const_iterator hint)
- {
- NodePtr p(AllocHolder::create_node());
- return iterator(this->icont().insert_equal(hint.get(), *p));
- }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_unique_impl \
- (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint_unique(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_unique_hint_impl \
- (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint_equal(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- return iterator(this->icont().insert_equal(hint.get(), *p)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator insert_unique(const_iterator hint, const value_type& v)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(hint, KeyOfValue()(v), data);
- if(!ret.second)
- return ret.first;
- return this->insert_unique_commit(v, data);
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class MovableConvertible>
- iterator insert_unique(const_iterator hint, detail::moved_object<MovableConvertible> mv)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(hint, KeyOfValue()(mv.get()), data);
- if(!ret.second)
- return ret.first;
- return this->insert_unique_commit(mv, data);
- }
- #else
- template<class MovableConvertible>
- iterator insert_unique
- (const_iterator hint, MovableConvertible &&mv)
- {
- insert_commit_data data;
- std::pair<iterator,bool> ret =
- this->insert_unique_check(hint, KeyOfValue()(mv), data);
- if(!ret.second)
- return ret.first;
- return this->insert_unique_commit(detail::forward_impl<MovableConvertible>(mv), data);
- }
- #endif
-
- template <class InputIterator>
- void insert_unique(InputIterator first, InputIterator last)
- {
- if(this->empty()){
- //Insert with end hint, to achieve linear
- //complexity if [first, last) is ordered
- const_iterator end(this->end());
- for( ; first != last; ++first)
- this->insert_unique(end, *first);
- }
- else{
- for( ; first != last; ++first)
- this->insert_unique(*first);
- }
- }
-
- iterator insert_equal(const value_type& v)
- {
- NodePtr p(AllocHolder::create_node(v));
- return iterator(this->icont().insert_equal(this->icont().end(), *p));
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class MovableConvertible>
- iterator insert_equal(detail::moved_object<MovableConvertible> mv)
- {
- NodePtr p(AllocHolder::create_node(mv));
- return iterator(this->icont().insert_equal(this->icont().end(), *p));
- }
- #else
- template<class MovableConvertible>
- iterator insert_equal(MovableConvertible &&mv)
- {
- NodePtr p(AllocHolder::create_node(detail::forward_impl<MovableConvertible>(mv)));
- return iterator(this->icont().insert_equal(this->icont().end(), *p));
- }
- #endif
-
- iterator insert_equal(const_iterator hint, const value_type& v)
- {
- NodePtr p(AllocHolder::create_node(v));
- return iterator(this->icont().insert_equal(hint.get(), *p));
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class MovableConvertible>
- iterator insert_equal(const_iterator hint, detail::moved_object<MovableConvertible> mv)
- {
- NodePtr p(AllocHolder::create_node(mv));
- return iterator(this->icont().insert_equal(hint.get(), *p));
- }
- #else
- template<class MovableConvertible>
- iterator insert_equal(const_iterator hint, MovableConvertible &&mv)
- {
- NodePtr p(AllocHolder::create_node(detail::move_impl(mv)));
- return iterator(this->icont().insert_equal(hint.get(), *p));
- }
- #endif
-
- template <class InputIterator>
- void insert_equal(InputIterator first, InputIterator last)
- {
- //Insert with end hint, to achieve linear
- //complexity if [first, last) is ordered
- const_iterator end(this->cend());
- for( ; first != last; ++first)
- this->insert_equal(end, *first);
- }
-
- iterator erase(const_iterator position)
- { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
-
- size_type erase(const key_type& k)
- { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
-
- iterator erase(const_iterator first, const_iterator last)
- { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
-
- void clear()
- { AllocHolder::clear(alloc_version()); }
-
- // set operations:
- iterator find(const key_type& k)
- { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
-
- const_iterator find(const key_type& k) const
- { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
-
- size_type count(const key_type& k) const
- { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
-
- iterator lower_bound(const key_type& k)
- { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
-
- const_iterator lower_bound(const key_type& k) const
- { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
-
- iterator upper_bound(const key_type& k)
- { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
-
- const_iterator upper_bound(const key_type& k) const
- { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
-
- std::pair<iterator,iterator> equal_range(const key_type& k)
- {
- std::pair<iiterator, iiterator> ret =
- this->icont().equal_range(k, KeyNodeCompare(value_comp()));
- return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
- }
-
- std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
- {
- std::pair<iiterator, iiterator> ret =
- this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
- return std::pair<const_iterator,const_iterator>
- (const_iterator(ret.first), const_iterator(ret.second));
- }
-
- private:
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (InpIterator beg, InpIterator end, bool unique)
- {
- typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(beg, end, unique, alloc_version(), ItCat());
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
- {
- if(unique){
- for (; beg != end; ++beg){
- this->insert_unique(*beg);
- }
- }
- else{
- for (; beg != end; ++beg){
- this->insert_equal(*beg);
- }
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
- }
-
- class insertion_functor;
- friend class insertion_functor;
-
- class insertion_functor
- {
- Icont &icont_;
-
- public:
- insertion_functor(Icont &icont)
- : icont_(icont)
- {}
-
- void operator()(Node &n)
- { this->icont_.insert_equal(this->icont_.cend(), n); }
- };
-
-
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
- {
- if(beg != end){
- if(unique){
- priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
- }
- else{
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont()));
- }
- }
- }
-};
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline bool
-operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
-{
- return x.size() == y.size() &&
- std::equal(x.begin(), x.end(), y.begin());
-}
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline bool
-operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
-{
- return std::lexicographical_compare(x.begin(), x.end(),
- y.begin(), y.end());
-}
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline bool
-operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
- return !(x == y);
-}
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline bool
-operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
- return y < x;
-}
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline bool
-operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
- return !(y < x);
-}
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline bool
-operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
- return !(x < y);
-}
-
-
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A>
-inline void
-swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
- rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
-{
- x.swap(y);
-}
-
-} //namespace detail {
-
-//!This class is movable
-template <class T, class V, class K, class C, class A>
-struct is_movable<detail::rbtree<T, V, K, C, A> >
-{
- enum { value = true };
-};
-
-//!This class is movable
-template <class T, class VoidPointer>
-struct is_movable<detail::rbtree_node<T, VoidPointer> >
-{
- enum { value = true };
-};
-
-//!This class is movable
-/*
-template <class A, class C>
-struct is_movable<detail::rbtree_alloc<A, C> >
-{
- enum { value = true };
-};
-*/
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class K, class V, class KOV,
- class C, class A>
-struct has_trivial_destructor_after_move<detail::rbtree<K, V, KOV, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_TREE_HPP
Modified: trunk/boost/interprocess/containers/flat_map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/flat_map.hpp (original)
+++ trunk/boost/interprocess/containers/flat_map.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -8,1434 +8,25 @@
//
//////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTERPROCESS_FLAT_MAP_HPP
-#define BOOST_INTERPROCESS_FLAT_MAP_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_FLAT_MAP_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_FLAT_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/flat_map.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <utility>
-#include <functional>
-#include <memory>
-#include <stdexcept>
-#include <boost/interprocess/containers/detail/flat_tree.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/move.hpp>
+namespace boost {
+namespace interprocess {
-namespace boost { namespace interprocess {
+using boost::interprocess_container::flat_map;
+using boost::interprocess_container::flat_multimap;
-/// @cond
-// Forward declarations of operators == and <, needed for friend declarations.
-template <class Key, class T, class Pred, class Alloc>
-class flat_map;
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y);
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y);
-/// @endcond
-
-//! A flat_map is a kind of associative container that supports unique keys (contains at
-//! most one of each key value) and provides for fast retrieval of values of another
-//! type T based on the keys. The flat_map class supports random-access iterators.
-//!
-//! A flat_map satisfies all of the requirements of a container and of a reversible
-//! container and of an associative container. A flat_map also provides
-//! most operations described for unique keys. For a
-//! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
-//! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
-//!
-//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
-//!
-//! Alloc is the allocator to allocate the value_types
-//! (e.g. <i>boost::interprocess:allocator< std::pair<Key, T></i>).
-//!
-//! flat_map is similar to std::map but it's implemented like an ordered vector.
-//! This means that inserting a new element into a flat_map invalidates
-//! previous iterators and references
-//!
-//! Erasing an element of a flat_map invalidates iterators and references
-//! pointing to elements that come after (their keys are bigger) the erased element.
-template <class Key, class T, class Pred, class Alloc>
-class flat_map
-{
- /// @cond
- private:
- //This is the tree that we should store if pair was movable
- typedef detail::flat_tree<Key,
- std::pair<Key, T>,
- detail::select1st< std::pair<Key, T> >,
- Pred,
- Alloc> tree_t;
-
- //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- //This is the real tree stored here. It's based on a movable pair
- typedef detail::flat_tree<Key,
- detail::pair<Key, T>,
- detail::select1st< detail::pair<Key, T> >,
- Pred,
- typename Alloc::template
- rebind<detail::pair<Key, T> >::other> impl_tree_t;
-/*
- #else
- typedef tree_t impl_tree_t;
- #endif
-*/
- impl_tree_t m_flat_tree; // flat tree representing flat_map
-
- typedef typename impl_tree_t::value_type impl_value_type;
- typedef typename impl_tree_t::pointer impl_pointer;
- typedef typename impl_tree_t::const_pointer impl_const_pointer;
- typedef typename impl_tree_t::reference impl_reference;
- typedef typename impl_tree_t::const_reference impl_const_reference;
- typedef typename impl_tree_t::value_compare impl_value_compare;
- typedef typename impl_tree_t::iterator impl_iterator;
- typedef typename impl_tree_t::const_iterator impl_const_iterator;
- typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
- typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
- typedef typename impl_tree_t::allocator_type impl_allocator_type;
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- typedef detail::moved_object<impl_value_type> impl_moved_value_type;
- #endif
-
- //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class D, class S>
- static D &force(const S &s)
- { return *const_cast<D*>(reinterpret_cast<const D*>(&s)); }
-
- template<class D, class S>
- static D force_copy(S s)
- {
- value_type *vp = reinterpret_cast<value_type *>(&*s);
- return D(vp);
- }
-
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef typename tree_t::value_compare value_compare;
- typedef T mapped_type;
- typedef typename tree_t::key_compare key_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- //! <b>Effects</b>: Constructs an empty flat_map using the specified
- //! comparison object and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit flat_map(const Pred& comp = Pred(), const allocator_type& a = allocator_type())
- : m_flat_tree(comp, force<impl_allocator_type>(a)) {}
-
- //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, force<impl_allocator_type>(a))
- { m_flat_tree.insert_unique(first, last); }
-
- //! <b>Effects</b>: Copy constructs a flat_map.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- flat_map(const flat_map<Key,T,Pred,Alloc>& x)
- : m_flat_tree(x.m_flat_tree) {}
-
- //! <b>Effects</b>: Move constructs a flat_map.
- //! Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_map(detail::moved_object<flat_map<Key,T,Pred,Alloc> > x)
- : m_flat_tree(detail::move_impl(x.get().m_flat_tree)) {}
-
- #else
- flat_map(flat_map<Key,T,Pred,Alloc> && x)
- : m_flat_tree(detail::move_impl(x.m_flat_tree)) {}
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- flat_map<Key,T,Pred,Alloc>& operator=(const flat_map<Key, T, Pred, Alloc>& x)
- { m_flat_tree = x.m_flat_tree; return *this; }
-
- //! <b>Effects</b>: Move constructs a flat_map.
- //! Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_map<Key,T,Pred,Alloc>& operator=(detail::moved_object<flat_map<Key, T, Pred, Alloc> > mx)
- { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
- #else
- flat_map<Key,T,Pred,Alloc>& operator=(flat_map<Key, T, Pred, Alloc> && mx)
- { m_flat_tree = detail::move_impl(mx.m_flat_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return force<key_compare>(m_flat_tree.key_comp()); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return force<allocator_type>(m_flat_tree.get_allocator()); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
-
- stored_allocator_type &get_stored_allocator()
- { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return force_copy<iterator>(m_flat_tree.begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return force<const_iterator>(m_flat_tree.begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return force<const_iterator>(m_flat_tree.cbegin()); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return force_copy<iterator>(m_flat_tree.end()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return force<const_iterator>(m_flat_tree.end()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return force<const_iterator>(m_flat_tree.cend()); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return force<reverse_iterator>(m_flat_tree.rbegin()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return force<const_reverse_iterator>(m_flat_tree.crbegin()); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return force<reverse_iterator>(m_flat_tree.rend()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return force<const_reverse_iterator>(m_flat_tree.rend()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return force<const_reverse_iterator>(m_flat_tree.crend()); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_flat_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_flat_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_flat_tree.max_size(); }
-
- //! Effects: If there is no key equivalent to x in the flat_map, inserts
- //! value_type(x, T()) into the flat_map.
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
- T &operator[](const key_type& k)
- {
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first))
- i = insert(i, value_type(k, T()));
- return (*i).second;
- }
-
- //! Effects: If there is no key equivalent to x in the flat_map, inserts
- //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- T &operator[](detail::moved_object<key_type> mk)
- {
- key_type &k = mk.get();
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first))
- i = insert(i, value_type(k, detail::move_impl(T())));
- return (*i).second;
- }
- #else
- T &operator[](key_type &&mk)
- {
- key_type &k = mk;
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first))
- i = insert(i, value_type(detail::forward_impl<key_type>(k), detail::move_impl(T())));
- return (*i).second;
- }
- #endif
-
- //! Returns: A reference to the element whose key is equivalent to x.
- //! Throws: An exception object of type out_of_range if no such element is present.
- //! Complexity: logarithmic.
- T& at(const key_type& k)
- {
- iterator i = this->find(k);
- if(i == this->end()){
- throw std::out_of_range("key not found");
- }
- return i->second;
- }
-
- //! Returns: A reference to the element whose key is equivalent to x.
- //! Throws: An exception object of type out_of_range if no such element is present.
- //! Complexity: logarithmic.
- const T& at(const key_type& k) const
- {
- const_iterator i = this->find(k);
- if(i == this->end()){
- throw std::out_of_range("key not found");
- }
- return i->second;
- }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<flat_map> x)
- { this->swap(x.get()); }
- void swap(flat_map& x)
- #else
- void swap(flat_map &&x)
- #endif
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Inserts x if and only if there is no element in the container
- //! with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- std::pair<iterator,bool> insert(const value_type& x)
- { return force<std::pair<iterator,bool> >(
- m_flat_tree.insert_unique(force<impl_value_type>(x))); }
-
- //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
- //! only if there is no element in the container with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
- { return force<std::pair<iterator,bool> >(
- m_flat_tree.insert_unique(force<impl_moved_value_type>(x))); }
- #else
- std::pair<iterator,bool> insert(value_type &&x)
- { return force<std::pair<iterator,bool> >(
- m_flat_tree.insert_unique(detail::move_impl(force<impl_value_type>(x)))); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const_iterator position, const value_type& x)
- { return force_copy<iterator>(
- m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
-
- //! <b>Effects</b>: Inserts an element move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, detail::moved_object<value_type> x)
- { return force_copy<iterator>(
- m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_moved_value_type>(x))); }
- #else
- iterator insert(const_iterator position, value_type &&x)
- { return force_copy<iterator>(
- m_flat_tree.insert_unique(force<impl_const_iterator>(position), detail::move_impl(force<impl_value_type>(x)))); }
- #endif
-
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) if and only
- //! if there is no element with key equivalent to the key of that element.
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- //! search time plus N*size() insertion time.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_flat_tree.insert_unique(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... if and only if there is no element in the container
- //! with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return force_copy<iterator>(m_flat_tree.emplace_unique(detail::forward_impl<Args>(args)...)); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint), detail::forward_impl<Args>(args)...)); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return force_copy<iterator>(m_flat_tree.emplace_unique()); }
-
- iterator emplace_hint(const_iterator hint)
- { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint))); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return force_copy<iterator>(m_flat_tree.emplace_unique \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return force_copy<iterator>(m_flat_tree.emplace_hint_unique \
- (force<impl_const_iterator>(hint), \
- BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by position.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Linear to the elements with keys bigger than position
- //!
- //! <b>Note</b>: Invalidates elements with keys
- //! not less than the erased element.
- iterator erase(const_iterator position)
- { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- size_type erase(const key_type& x)
- { return m_flat_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: size()*N where N is the distance from first to last.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- iterator erase(const_iterator first, const_iterator last)
- { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_flat_tree.clear(); }
-
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- // with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { m_flat_tree.shrink_to_fit(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return force_copy<iterator>(m_flat_tree.find(x)); }
-
- //! <b>Returns</b>: A const_iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.s
- const_iterator find(const key_type& x) const
- { return force<const_iterator>(m_flat_tree.find(x)); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- { return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return force<const_iterator>(m_flat_tree.lower_bound(x)); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return force<const_iterator>(m_flat_tree.upper_bound(x)); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
- { return force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
- { return force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return m_flat_tree.capacity(); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
- //!
- //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
- //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
- //! to values might be invalidated.
- void reserve(size_type count)
- { m_flat_tree.reserve(count); }
-
- /// @cond
- template <class K1, class T1, class C1, class A1>
- friend bool operator== (const flat_map<K1, T1, C1, A1>&,
- const flat_map<K1, T1, C1, A1>&);
- template <class K1, class T1, class C1, class A1>
- friend bool operator< (const flat_map<K1, T1, C1, A1>&,
- const flat_map<K1, T1, C1, A1>&);
- /// @endcond
-};
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y)
- { return x.m_flat_tree == y.m_flat_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y)
- { return x.m_flat_tree < y.m_flat_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator!=(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y)
- { return !(x == y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y)
- { return y < x; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<=(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y)
- { return !(y < x); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>=(const flat_map<Key,T,Pred,Alloc>& x,
- const flat_map<Key,T,Pred,Alloc>& y)
- { return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(flat_map<Key,T,Pred,Alloc>& x,
- flat_map<Key,T,Pred,Alloc>& y)
- { x.swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<flat_map<Key,T,Pred,Alloc> > x,
- flat_map<Key,T,Pred,Alloc>& y)
- { x.get().swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(flat_map<Key,T,Pred,Alloc>& x,
- detail::moved_object<flat_map<Key,T,Pred,Alloc> > y)
- { x.swap(y.get()); }
-#else
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(flat_map<Key,T,Pred,Alloc>&&x,
- flat_map<Key,T,Pred,Alloc>&&y)
- { x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class K, class T, class C, class A>
-struct is_movable<flat_map<K, T, C, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<flat_map<K, T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-
-// Forward declaration of operators < and ==, needed for friend declaration.
-template <class Key, class T,
- class Pred,
- class Alloc>
-class flat_multimap;
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y);
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y);
-/// @endcond
-
-//! A flat_multimap is a kind of associative container that supports equivalent keys
-//! (possibly containing multiple copies of the same key value) and provides for
-//! fast retrieval of values of another type T based on the keys. The flat_multimap
-//! class supports random-access iterators.
-//!
-//! A flat_multimap satisfies all of the requirements of a container and of a reversible
-//! container and of an associative container. For a
-//! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
-//! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
-//!
-//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
-//!
-//! Alloc is the allocator to allocate the value_types
-//! (e.g. <i>boost::interprocess:allocator< std::pair<Key, T></i>).
-template <class Key, class T, class Pred, class Alloc>
-class flat_multimap
-{
- /// @cond
- private:
- typedef detail::flat_tree<Key,
- std::pair<Key, T>,
- detail::select1st< std::pair<Key, T> >,
- Pred,
- Alloc> tree_t;
- //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- //This is the real tree stored here. It's based on a movable pair
- typedef detail::flat_tree<Key,
- detail::pair<Key, T>,
- detail::select1st< detail::pair<Key, T> >,
- Pred,
- typename Alloc::template
- rebind<detail::pair<Key, T> >::other> impl_tree_t;
-/*
- #else
- typedef tree_t impl_tree_t;
- #endif
-*/
- impl_tree_t m_flat_tree; // flat tree representing flat_map
-
- typedef typename impl_tree_t::value_type impl_value_type;
- typedef typename impl_tree_t::pointer impl_pointer;
- typedef typename impl_tree_t::const_pointer impl_const_pointer;
- typedef typename impl_tree_t::reference impl_reference;
- typedef typename impl_tree_t::const_reference impl_const_reference;
- typedef typename impl_tree_t::value_compare impl_value_compare;
- typedef typename impl_tree_t::iterator impl_iterator;
- typedef typename impl_tree_t::const_iterator impl_const_iterator;
- typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
- typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
- typedef typename impl_tree_t::allocator_type impl_allocator_type;
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- typedef detail::moved_object<impl_value_type> impl_moved_value_type;
- #endif
-
- //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class D, class S>
- static D &force(const S &s)
- { return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
-
- template<class D, class S>
- static D force_copy(S s)
- {
- value_type *vp = reinterpret_cast<value_type *>(&*s);
- return D(vp);
- }
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef typename tree_t::value_compare value_compare;
- typedef T mapped_type;
- typedef typename tree_t::key_compare key_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
- //! object and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit flat_multimap(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, force<impl_allocator_type>(a)) { }
-
- //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
- //! and allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- flat_multimap(InputIterator first, InputIterator last,
- const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, force<impl_allocator_type>(a))
- { m_flat_tree.insert_equal(first, last); }
-
- //! <b>Effects</b>: Copy constructs a flat_multimap.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- flat_multimap(const flat_multimap<Key,T,Pred,Alloc>& x)
- : m_flat_tree(x.m_flat_tree) { }
-
- //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_multimap(detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > x)
- : m_flat_tree(detail::move_impl(x.get().m_flat_tree)) { }
- #else
- flat_multimap(flat_multimap<Key,T,Pred,Alloc> && x)
- : m_flat_tree(detail::move_impl(x.m_flat_tree)) { }
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- flat_multimap<Key,T,Pred,Alloc>& operator=(const flat_multimap<Key,T,Pred,Alloc>& x)
- { m_flat_tree = x.m_flat_tree; return *this; }
-
- //! <b>Effects</b>: this->swap(x.get()).
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_multimap<Key,T,Pred,Alloc>& operator=(detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > mx)
- { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
- #else
- flat_multimap<Key,T,Pred,Alloc>& operator=(flat_multimap<Key,T,Pred,Alloc> && mx)
- { m_flat_tree = detail::move_impl(mx.m_flat_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return force<key_compare>(m_flat_tree.key_comp()); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return force<allocator_type>(m_flat_tree.get_allocator()); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
-
- stored_allocator_type &get_stored_allocator()
- { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return force_copy<iterator>(m_flat_tree.begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return force<const_iterator>(m_flat_tree.begin()); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return force_copy<iterator>(m_flat_tree.end()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return force<const_iterator>(m_flat_tree.end()); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return force<reverse_iterator>(m_flat_tree.rbegin()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return force<reverse_iterator>(m_flat_tree.rend()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return force<const_reverse_iterator>(m_flat_tree.rend()); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_flat_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_flat_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_flat_tree.max_size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<flat_multimap> x)
- { this->swap(x.get()); }
- void swap(flat_multimap& x)
- #else
- void swap(flat_multimap &&x)
- #endif
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const value_type& x)
- { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_value_type>(x))); }
-
- //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
- //! the iterator pointing to the newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(detail::moved_object<value_type> x)
- { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_moved_value_type>(x))); }
- #else
- iterator insert(value_type &&x)
- { return force_copy<iterator>(m_flat_tree.insert_equal(detail::move_impl(x))); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant time if the value
- //! is to be inserted before p) plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const_iterator position, const value_type& x)
- { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
-
- //! <b>Effects</b>: Inserts a value move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant time if the value
- //! is to be inserted before p) plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, detail::moved_object<value_type> x)
- { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_moved_value_type>(x))); }
- #else
- iterator insert(const_iterator position, value_type &&x)
- { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), detail::move_impl(x))); }
- #endif
-
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) .
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- //! search time plus N*size() insertion time.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_flat_tree.insert_equal(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return force_copy<iterator>(m_flat_tree.emplace_equal(detail::forward_impl<Args>(args)...)); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant time if the value
- //! is to be inserted before p) plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- {
- return force_copy<iterator>(m_flat_tree.emplace_hint_equal
- (force<impl_const_iterator>(hint), detail::forward_impl<Args>(args)...));
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return force_copy<iterator>(m_flat_tree.emplace_equal()); }
-
- iterator emplace_hint(const_iterator hint)
- { return force_copy<iterator>(m_flat_tree.emplace_hint_equal(force<impl_const_iterator>(hint))); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return force_copy<iterator>(m_flat_tree.emplace_equal \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return force_copy<iterator>(m_flat_tree.emplace_hint_equal \
- (force<impl_const_iterator>(hint), \
- BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by position.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Linear to the elements with keys bigger than position
- //!
- //! <b>Note</b>: Invalidates elements with keys
- //! not less than the erased element.
- iterator erase(const_iterator position)
- { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- size_type erase(const key_type& x)
- { return m_flat_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: size()*N where N is the distance from first to last.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- iterator erase(const_iterator first, const_iterator last)
- { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_flat_tree.clear(); }
-
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- // with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { m_flat_tree.shrink_to_fit(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return force_copy<iterator>(m_flat_tree.find(x)); }
-
- //! <b>Returns</b>: An const_iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
- { return force<const_iterator>(m_flat_tree.find(x)); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_flat_tree.count(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- {return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key
- //! not less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return force<const_iterator>(m_flat_tree.lower_bound(x)); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- {return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key
- //! not less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return force<const_iterator>(m_flat_tree.upper_bound(x)); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
- { return force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator,const_iterator>
- equal_range(const key_type& x) const
- { return force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return m_flat_tree.capacity(); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
- //!
- //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
- //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
- //! to values might be invalidated.
- void reserve(size_type count)
- { m_flat_tree.reserve(count); }
-
- /// @cond
- template <class K1, class T1, class C1, class A1>
- friend bool operator== (const flat_multimap<K1, T1, C1, A1>& x,
- const flat_multimap<K1, T1, C1, A1>& y);
-
- template <class K1, class T1, class C1, class A1>
- friend bool operator< (const flat_multimap<K1, T1, C1, A1>& x,
- const flat_multimap<K1, T1, C1, A1>& y);
- /// @endcond
-};
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y)
- { return x.m_flat_tree == y.m_flat_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y)
- { return x.m_flat_tree < y.m_flat_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator!=(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y)
- { return !(x == y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y)
- { return y < x; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<=(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y)
- { return !(y < x); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>=(const flat_multimap<Key,T,Pred,Alloc>& x,
- const flat_multimap<Key,T,Pred,Alloc>& y)
- { return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(flat_multimap<Key,T,Pred,Alloc>& x,
- flat_multimap<Key,T,Pred,Alloc>& y)
- { x.swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > x,
- flat_multimap<Key,T,Pred,Alloc>& y)
- { x.get().swap(y); }
-
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(flat_multimap<Key,T,Pred,Alloc>& x,
- detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > y)
- { x.swap(y.get()); }
-#else
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(flat_multimap<Key,T,Pred,Alloc>&&x,
- flat_multimap<Key,T,Pred,Alloc>&&y)
- { x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class K, class T, class C, class A>
-struct is_movable<flat_multimap<K, T, C, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<flat_multimap<K, T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-/// @endcond
-
-}} //namespace boost { namespace interprocess {
+} //namespace interprocess {
+} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_FLAT_MAP_HPP */
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_FLAT_MAP_HPP
Modified: trunk/boost/interprocess/containers/flat_set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/flat_set.hpp (original)
+++ trunk/boost/interprocess/containers/flat_set.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -8,1237 +8,25 @@
//
//////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTERPROCESS_FLAT_SET_HPP
-#define BOOST_INTERPROCESS_FLAT_SET_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_FLAT_SET_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_FLAT_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/flat_set.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <utility>
-#include <functional>
-#include <memory>
-#include <boost/interprocess/containers/detail/flat_tree.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/move.hpp>
+namespace boost {
+namespace interprocess {
+using boost::interprocess_container::flat_set;
+using boost::interprocess_container::flat_multiset;
-namespace boost { namespace interprocess {
-
-/// @cond
-// Forward declarations of operators < and ==, needed for friend declaration.
-
-template <class T, class Pred, class Alloc>
-class flat_set;
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y);
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y);
-/// @endcond
-
-//! flat_set is a Sorted Associative Container that stores objects of type Key.
-//! flat_set is a Simple Associative Container, meaning that its value type,
-//! as well as its key type, is Key. It is also a Unique Associative Container,
-//! meaning that no two elements are the same.
-//!
-//! flat_set is similar to std::set but it's implemented like an ordered vector.
-//! This means that inserting a new element into a flat_set invalidates
-//! previous iterators and references
-//!
-//! Erasing an element of a flat_set invalidates iterators and references
-//! pointing to elements that come after (their keys are bigger) the erased element.
-template <class T, class Pred, class Alloc>
-class flat_set
-{
- /// @cond
- private:
- typedef detail::flat_tree<T, T, detail::identity<T>, Pred, Alloc> tree_t;
- tree_t m_flat_tree; // flat tree representing flat_set
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef typename tree_t::key_compare key_compare;
- typedef typename tree_t::value_compare value_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- //! <b>Effects</b>: Constructs an empty flat_map using the specified
- //! comparison object and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit flat_set(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, a)
- {}
-
- //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- flat_set(InputIterator first, InputIterator last,
- const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, a)
- { m_flat_tree.insert_unique(first, last); }
-
- //! <b>Effects</b>: Copy constructs a map.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- flat_set(const flat_set<T,Pred,Alloc>& x)
- : m_flat_tree(x.m_flat_tree) {}
-
- //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_set(detail::moved_object<flat_set<T,Pred,Alloc> > mx)
- : m_flat_tree(detail::move_impl(mx.get().m_flat_tree)) {}
- #else
- flat_set(flat_set<T,Pred,Alloc> && mx)
- : m_flat_tree(detail::move_impl(mx.m_flat_tree)) {}
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- flat_set<T,Pred,Alloc>& operator=(const flat_set<T, Pred, Alloc>& x)
- { m_flat_tree = x.m_flat_tree; return *this; }
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_set<T,Pred,Alloc>& operator=(detail::moved_object<flat_set<T, Pred, Alloc> > mx)
- { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
-
- #else
- flat_set<T,Pred,Alloc>& operator=(flat_set<T, Pred, Alloc> &&mx)
- { m_flat_tree = detail::move_impl(mx.m_flat_tree); return *this; }
-
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return m_flat_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return m_flat_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return m_flat_tree.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return m_flat_tree.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return m_flat_tree.get_stored_allocator(); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return m_flat_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return m_flat_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return m_flat_tree.cbegin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return m_flat_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return m_flat_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return m_flat_tree.cend(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return m_flat_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return m_flat_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return m_flat_tree.crbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return m_flat_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return m_flat_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return m_flat_tree.crend(); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_flat_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_flat_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_flat_tree.max_size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<flat_set> x)
- { this->swap(x.get()); }
- void swap(flat_set& x)
- #else
- void swap(flat_set &&x)
- #endif
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Inserts x if and only if there is no element in the container
- //! with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- std::pair<iterator,bool> insert(const value_type& x)
- { return m_flat_tree.insert_unique(x); }
-
- //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
- //! only if there is no element in the container with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
- { return m_flat_tree.insert_unique(x); }
- #else
- std::pair<iterator,bool> insert(value_type && x)
- { return m_flat_tree.insert_unique(detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const_iterator position, const value_type& x)
- { return m_flat_tree.insert_unique(position, x); }
-
- //! <b>Effects</b>: Inserts an element move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, detail::moved_object<value_type> x)
- { return m_flat_tree.insert_unique(position, x); }
- #else
- iterator insert(const_iterator position, value_type && x)
- { return m_flat_tree.insert_unique(position, detail::move_impl(x)); }
- #endif
-
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) if and only
- //! if there is no element with key equivalent to the key of that element.
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- //! search time plus N*size() insertion time.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_flat_tree.insert_unique(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... if and only if there is no element in the container
- //! with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return m_flat_tree.emplace_unique(detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return m_flat_tree.emplace_hint_unique(hint, detail::forward_impl<Args>(args)...); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return m_flat_tree.emplace_unique(); }
-
- iterator emplace_hint(const_iterator hint)
- { return m_flat_tree.emplace_hint_unique(hint); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_flat_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); }\
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by position.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Linear to the elements with keys bigger than position
- //!
- //! <b>Note</b>: Invalidates elements with keys
- //! not less than the erased element.
- iterator erase(const_iterator position)
- { return m_flat_tree.erase(position); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- size_type erase(const key_type& x)
- { return m_flat_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: size()*N where N is the distance from first to last.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- iterator erase(const_iterator first, const_iterator last)
- { return m_flat_tree.erase(first, last); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_flat_tree.clear(); }
-
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- // with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { m_flat_tree.shrink_to_fit(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return m_flat_tree.find(x); }
-
- //! <b>Returns</b>: A const_iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.s
- const_iterator find(const key_type& x) const
- { return m_flat_tree.find(x); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- { return m_flat_tree.lower_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return m_flat_tree.lower_bound(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return m_flat_tree.upper_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return m_flat_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& x) const
- { return m_flat_tree.equal_range(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator>
- equal_range(const key_type& x)
- { return m_flat_tree.equal_range(x); }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return m_flat_tree.capacity(); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
- //!
- //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
- //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
- //! to values might be invalidated.
- void reserve(size_type count)
- { m_flat_tree.reserve(count); }
-
- /// @cond
- template <class K1, class C1, class A1>
- friend bool operator== (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
-
- template <class K1, class C1, class A1>
- friend bool operator< (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
- /// @endcond
-};
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y)
- { return x.m_flat_tree == y.m_flat_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y)
- { return x.m_flat_tree < y.m_flat_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator!=(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y)
- { return !(x == y); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y)
- { return y < x; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<=(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y)
- { return !(y < x); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>=(const flat_set<T,Pred,Alloc>& x,
- const flat_set<T,Pred,Alloc>& y)
- { return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class Pred, class Alloc>
-inline void swap(flat_set<T,Pred,Alloc>& x, flat_set<T,Pred,Alloc>& y)
- { x.swap(y); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<flat_set<T,Pred,Alloc> > x, flat_set<T,Pred,Alloc>& y)
- { x.get().swap(y); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(flat_set<T,Pred,Alloc>& x, detail::moved_object<flat_set<T,Pred,Alloc> > y)
- { x.swap(y.get()); }
-#else
-template <class T, class Pred, class Alloc>
-inline void swap(flat_set<T,Pred,Alloc>&&x, flat_set<T,Pred,Alloc>&&y)
- { x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class P, class A>
-struct is_movable<flat_set<T, P, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class C, class A>
-struct has_trivial_destructor_after_move<flat_set<T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-
-// Forward declaration of operators < and ==, needed for friend declaration.
-
-template <class T, class Pred, class Alloc>
-class flat_multiset;
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y);
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y);
-/// @endcond
-
-//! flat_multiset is a Sorted Associative Container that stores objects of type Key.
-//! flat_multiset is a Simple Associative Container, meaning that its value type,
-//! as well as its key type, is Key.
-//! flat_Multiset can store multiple copies of the same key value.
-//!
-//! flat_multiset is similar to std::multiset but it's implemented like an ordered vector.
-//! This means that inserting a new element into a flat_multiset invalidates
-//! previous iterators and references
-//!
-//! Erasing an element of a flat_multiset invalidates iterators and references
-//! pointing to elements that come after (their keys are equal or bigger) the erased element.
-template <class T, class Pred, class Alloc>
-class flat_multiset
-{
- /// @cond
- private:
- typedef detail::flat_tree<T, T, detail::identity<T>, Pred, Alloc> tree_t;
- tree_t m_flat_tree; // flat tree representing flat_multiset
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef typename tree_t::key_compare key_compare;
- typedef typename tree_t::value_compare value_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- // allocation/deallocation
- explicit flat_multiset(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, a) {}
-
- template <class InputIterator>
- flat_multiset(InputIterator first, InputIterator last,
- const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_flat_tree(comp, a)
- { m_flat_tree.insert_equal(first, last); }
-
- flat_multiset(const flat_multiset<T,Pred,Alloc>& x)
- : m_flat_tree(x.m_flat_tree) {}
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_multiset(detail::moved_object<flat_multiset<T,Pred,Alloc> > x)
- : m_flat_tree(detail::move_impl(x.get().m_flat_tree)) {}
- #else
- flat_multiset(flat_multiset<T,Pred,Alloc> && x)
- : m_flat_tree(detail::move_impl(x.m_flat_tree)) {}
- #endif
-
- flat_multiset<T,Pred,Alloc>& operator=(const flat_multiset<T,Pred,Alloc>& x)
- { m_flat_tree = x.m_flat_tree; return *this; }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- flat_multiset<T,Pred,Alloc>& operator=(detail::moved_object<flat_multiset<T,Pred,Alloc> > mx)
- { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
- #else
- flat_multiset<T,Pred,Alloc>& operator=(flat_multiset<T,Pred,Alloc> && mx)
- { m_flat_tree = detail::move_impl(mx.m_flat_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return m_flat_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return m_flat_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return m_flat_tree.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return m_flat_tree.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return m_flat_tree.get_stored_allocator(); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return m_flat_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return m_flat_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return m_flat_tree.cbegin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return m_flat_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return m_flat_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return m_flat_tree.cend(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return m_flat_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return m_flat_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return m_flat_tree.crbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return m_flat_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return m_flat_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return m_flat_tree.crend(); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_flat_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_flat_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_flat_tree.max_size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<flat_multiset> x)
- { this->swap(x.get()); }
- void swap(flat_multiset& x)
- #else
- void swap(flat_multiset &&x)
- #endif
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const value_type& x)
- { return m_flat_tree.insert_equal(x); }
-
- //! <b>Effects</b>: Inserts a new value_type move constructed from x
- //! and returns the iterator pointing to the newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(detail::moved_object<value_type> x)
- { return m_flat_tree.insert_equal(x); }
- #else
- iterator insert(value_type && x)
- { return m_flat_tree.insert_equal(detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const_iterator position, const value_type& x)
- { return m_flat_tree.insert_equal(position, x); }
-
- //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, detail::moved_object<value_type> x)
- { return m_flat_tree.insert_equal(position, x); }
- #else
- iterator insert(const_iterator position, value_type && x)
- { return m_flat_tree.insert_equal(position, detail::move_impl(x)); }
- #endif
-
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) .
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- //! search time plus N*size() insertion time.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_flat_tree.insert_equal(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus linear insertion
- //! to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return m_flat_tree.emplace_equal(detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
- //! right before p) plus insertion linear to the elements with bigger keys than x.
- //!
- //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return m_flat_tree.emplace_hint_equal(hint, detail::forward_impl<Args>(args)...); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return m_flat_tree.emplace_equal(); }
-
- iterator emplace_hint(const_iterator hint)
- { return m_flat_tree.emplace_hint_equal(hint); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_flat_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by position.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Linear to the elements with keys bigger than position
- //!
- //! <b>Note</b>: Invalidates elements with keys
- //! not less than the erased element.
- iterator erase(const_iterator position)
- { return m_flat_tree.erase(position); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- size_type erase(const key_type& x)
- { return m_flat_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: size()*N where N is the distance from first to last.
- //!
- //! <b>Complexity</b>: Logarithmic search time plus erasure time
- //! linear to the elements with bigger keys.
- iterator erase(const_iterator first, const_iterator last)
- { return m_flat_tree.erase(first, last); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_flat_tree.clear(); }
-
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- // with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { m_flat_tree.shrink_to_fit(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return m_flat_tree.find(x); }
-
- //! <b>Returns</b>: A const_iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.s
- const_iterator find(const key_type& x) const
- { return m_flat_tree.find(x); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_flat_tree.count(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- { return m_flat_tree.lower_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return m_flat_tree.lower_bound(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return m_flat_tree.upper_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return m_flat_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& x) const
- { return m_flat_tree.equal_range(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator>
- equal_range(const key_type& x)
- { return m_flat_tree.equal_range(x); }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return m_flat_tree.capacity(); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
- //!
- //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
- //!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
- //! to values might be invalidated.
- void reserve(size_type count)
- { m_flat_tree.reserve(count); }
-
- /// @cond
- template <class K1, class C1, class A1>
- friend bool operator== (const flat_multiset<K1,C1,A1>&,
- const flat_multiset<K1,C1,A1>&);
- template <class K1, class C1, class A1>
- friend bool operator< (const flat_multiset<K1,C1,A1>&,
- const flat_multiset<K1,C1,A1>&);
- /// @endcond
-};
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y)
- { return x.m_flat_tree == y.m_flat_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y)
- { return x.m_flat_tree < y.m_flat_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator!=(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y)
- { return !(x == y); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y)
- { return y < x; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<=(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y)
- { return !(y < x); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>=(const flat_multiset<T,Pred,Alloc>& x,
- const flat_multiset<T,Pred,Alloc>& y)
-{ return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class Pred, class Alloc>
-inline void swap(flat_multiset<T,Pred,Alloc>& x, flat_multiset<T,Pred,Alloc>& y)
- { x.swap(y); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<flat_multiset<T,Pred,Alloc> > x, flat_multiset<T,Pred,Alloc>& y)
- { x.get().swap(y); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(flat_multiset<T,Pred,Alloc>& x, detail::moved_object<flat_multiset<T,Pred,Alloc> > y)
- { x.swap(y.get()); }
-#else
-template <class T, class Pred, class Alloc>
-inline void swap(flat_multiset<T,Pred,Alloc>&&x, flat_multiset<T,Pred,Alloc>&&y)
- { x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class P, class A>
-struct is_movable<flat_multiset<T, P, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class C, class A>
-struct has_trivial_destructor_after_move<flat_multiset<T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-/// @endcond
-
-}} //namespace boost { namespace interprocess {
+} //namespace interprocess {
+} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_FLAT_SET_HPP */
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_FLAT_SET_HPP
Modified: trunk/boost/interprocess/containers/list.hpp
==============================================================================
--- trunk/boost/interprocess/containers/list.hpp (original)
+++ trunk/boost/interprocess/containers/list.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,1469 +1,32 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_list.h file. Modified by Ion Gaztanaga 2004
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-/*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef BOOST_INTERPROCESS_LIST_HPP_
-#define BOOST_INTERPROCESS_LIST_HPP_
+#ifndef BOOST_INTERPROCESS_CONTAINERS_LIST_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_LIST_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/intrusive/list.hpp>
-#include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
-
-#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-//Preprocessor library to emulate perfect forwarding
-#include <boost/interprocess/detail/preprocessor.hpp>
-#endif
-
-#include <iterator>
-#include <utility>
-#include <memory>
-#include <functional>
-#include <algorithm>
-#include <stdexcept>
+#include <boost/interprocess/containers/container/list.hpp>
namespace boost {
namespace interprocess {
-/// @cond
-namespace detail {
-
-template<class VoidPointer>
-struct list_hook
-{
- typedef typename bi::make_list_base_hook
- <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type type;
-};
-
-template <class T, class VoidPointer>
-struct list_node
- : public list_hook<VoidPointer>::type
-{
-
- #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- list_node()
- : m_data()
- {}
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- list_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #else //#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template<class ...Args>
- list_node(Args &&...args)
- : m_data(detail::forward_impl<Args>(args)...)
- {}
- #endif//#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- T m_data;
-};
-
-template<class A>
-struct intrusive_list_type
-{
- typedef typename A::value_type value_type;
- typedef typename detail::pointer_to_other
- <typename A::pointer, void>::type void_pointer;
- typedef typename detail::list_node
- <value_type, void_pointer> node_type;
- typedef typename bi::make_list
- < node_type
- , bi::base_hook<typename list_hook<void_pointer>::type>
- , bi::constant_time_size<true>
- , bi::size_type<typename A::size_type>
- >::type container_type;
- typedef container_type type ;
-};
-
-} //namespace detail {
-/// @endcond
-
-//! A list is a doubly linked list. That is, it is a Sequence that supports both
-//! forward and backward traversal, and (amortized) constant time insertion and
-//! removal of elements at the beginning or the end, or in the middle. Lists have
-//! the important property that insertion and splicing do not invalidate iterators
-//! to list elements, and that even removal invalidates only the iterators that point
-//! to the elements that are removed. The ordering of iterators may be changed
-//! (that is, list<T>::iterator might have a different predecessor or successor
-//! after a list operation than it did before), but the iterators themselves will
-//! not be invalidated or made to point to different elements unless that invalidation
-//! or mutation is explicit.
-template <class T, class A>
-class list
- : protected detail::node_alloc_holder
- <A, typename detail::intrusive_list_type<A>::type>
-{
- /// @cond
- typedef typename
- detail::intrusive_list_type<A>::type Icont;
- typedef list <T, A> ThisType;
- typedef detail::node_alloc_holder<A, Icont> AllocHolder;
- typedef typename AllocHolder::NodePtr NodePtr;
- typedef typename AllocHolder::NodeAlloc NodeAlloc;
- typedef typename AllocHolder::ValAlloc ValAlloc;
- typedef typename AllocHolder::Node Node;
- typedef detail::allocator_destroyer<NodeAlloc> Destroyer;
- typedef typename AllocHolder::allocator_v1 allocator_v1;
- typedef typename AllocHolder::allocator_v2 allocator_v2;
- typedef typename AllocHolder::alloc_version alloc_version;
-
- class equal_to_value
- {
- typedef typename AllocHolder::value_type value_type;
- const value_type &t_;
-
- public:
- equal_to_value(const value_type &t)
- : t_(t)
- {}
-
- bool operator()(const value_type &t)const
- { return t_ == t; }
- };
-
- template<class Pred>
- struct ValueCompareToNodeCompare
- : Pred
- {
- ValueCompareToNodeCompare(Pred pred)
- : Pred(pred)
- {}
-
- bool operator()(const Node &a, const Node &b) const
- { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
-
- bool operator()(const Node &a) const
- { return static_cast<const Pred&>(*this)(a.m_data); }
- };
- /// @endcond
-
- public:
- //! The type of object, T, stored in the list
- typedef T value_type;
- //! Pointer to T
- typedef typename A::pointer pointer;
- //! Const pointer to T
- typedef typename A::const_pointer const_pointer;
- //! Reference to T
- typedef typename A::reference reference;
- //! Const reference to T
- typedef typename A::const_reference const_reference;
- //! An unsigned integral type
- typedef typename A::size_type size_type;
- //! A signed integral type
- typedef typename A::difference_type difference_type;
- //! The allocator type
- typedef A allocator_type;
- //! The stored allocator type
- typedef NodeAlloc stored_allocator_type;
-
- /// @cond
- private:
- typedef difference_type list_difference_type;
- typedef pointer list_pointer;
- typedef const_pointer list_const_pointer;
- typedef reference list_reference;
- typedef const_reference list_const_reference;
- /// @endcond
-
- public:
- //! Const iterator used to iterate through a list.
- class const_iterator
- /// @cond
- : public std::iterator<std::bidirectional_iterator_tag,
- value_type, list_difference_type,
- list_const_pointer, list_const_reference>
- {
-
- protected:
- typename Icont::iterator m_it;
- explicit const_iterator(typename Icont::iterator it) : m_it(it){}
- void prot_incr() { ++m_it; }
- void prot_decr() { --m_it; }
-
- private:
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class list<T, A>;
- typedef list_difference_type difference_type;
-
- //Constructors
- const_iterator()
- : m_it()
- {}
-
- //Pointer like operators
- const_reference operator*() const
- { return m_it->m_data; }
-
- const_pointer operator->() const
- { return const_pointer(&m_it->m_data); }
-
- //Increment / Decrement
- const_iterator& operator++()
- { prot_incr(); return *this; }
-
- const_iterator operator++(int)
- { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
-
- const_iterator& operator--()
- { prot_decr(); return *this; }
-
- const_iterator operator--(int)
- { typename Icont::iterator tmp = m_it; --*this; return const_iterator(tmp); }
-
- //Comparison operators
- bool operator== (const const_iterator& r) const
- { return m_it == r.m_it; }
-
- bool operator!= (const const_iterator& r) const
- { return m_it != r.m_it; }
- }
- /// @endcond
- ;
-
- //! Iterator used to iterate through a list
- class iterator
- /// @cond
- : public const_iterator
- {
-
- private:
- explicit iterator(typename Icont::iterator it)
- : const_iterator(it)
- {}
-
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class list<T, A>;
- typedef list_pointer pointer;
- typedef list_reference reference;
-
- //Constructors
- iterator(){}
-
- //Pointer like operators
- reference operator*() const { return this->m_it->m_data; }
- pointer operator->() const { return pointer(&this->m_it->m_data); }
-
- //Increment / Decrement
- iterator& operator++()
- { this->prot_incr(); return *this; }
-
- iterator operator++(int)
- { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
-
- iterator& operator--()
- { this->prot_decr(); return *this; }
-
- iterator operator--(int)
- { iterator tmp = *this; --*this; return tmp; }
- }
- /// @endcond
- ;
-
- //! Iterator used to iterate backwards through a list.
- typedef std::reverse_iterator<iterator> reverse_iterator;
- //! Const iterator used to iterate backwards through a list.
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- explicit list(const allocator_type &a = A())
- : AllocHolder(a)
- {}
-
-// list(size_type n)
-// : AllocHolder(detail::move_impl(allocator_type()))
-// { this->resize(n); }
-
- //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
- //! and inserts n copies of value.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
- //! throws or T's default or copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- list(size_type n, const T& value = T(), const A& a = A())
- : AllocHolder(a)
- { this->insert(this->cbegin(), n, value); }
-
- //! <b>Effects</b>: Copy constructs a list.
- //!
- //! <b>Postcondition</b>: x == *this.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the elements x contains.
- list(const list& x)
- : AllocHolder(x)
- { this->insert(this->cbegin(), x.begin(), x.end()); }
-
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- list(detail::moved_object<list> x)
- : AllocHolder(detail::move_impl((AllocHolder&)x.get()))
- {}
- #else
- list(list &&x)
- : AllocHolder(detail::move_impl((AllocHolder&)x))
- {}
- #endif
-
- //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
- //! and inserts a copy of the range [first, last) in the list.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
- //! throws or T's constructor taking an dereferenced InIt throws.
- //!
- //! <b>Complexity</b>: Linear to the range [first, last).
- template <class InpIt>
- list(InpIt first, InpIt last, const A &a = A())
- : AllocHolder(a)
- { this->insert(this->cbegin(), first, last); }
-
- //! <b>Effects</b>: Destroys the list. All stored values are destroyed
- //! and used memory is deallocated.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements.
- ~list()
- {} //AllocHolder clears the list
-
- //! <b>Effects</b>: Returns a copy of the internal allocator.
- //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return allocator_type(this->node_alloc()); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return this->node_alloc(); }
-
- stored_allocator_type &get_stored_allocator()
- { return this->node_alloc(); }
-
- //! <b>Effects</b>: Erases all the elements of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the list.
- void clear()
- { AllocHolder::clear(alloc_version()); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return iterator(this->icont().begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return this->cbegin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return iterator(this->icont().end()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return this->cend(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return reverse_iterator(end()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return this->crbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return reverse_iterator(begin()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return this->crend(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return const_iterator(this->non_const_icont().begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return const_iterator(this->non_const_icont().end()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return const_reverse_iterator(this->cend()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return const_reverse_iterator(this->cbegin()); }
-
- //! <b>Effects</b>: Returns true if the list contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->size(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return this->icont().size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return AllocHolder::max_size(); }
-
- //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_front(const T& x)
- { this->insert(this->cbegin(), x); }
-
- //! <b>Effects</b>: Constructs a new element in the beginning of the list
- //! and moves the resources of t to this new element.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void push_front(detail::moved_object<T> x)
- { this->insert(this->cbegin(), x); }
- #else
- void push_front(T &&x)
- { this->insert(this->cbegin(), detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Removes the last element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_back (const T& x)
- { this->insert(this->cend(), x); }
-
- //! <b>Effects</b>: Removes the first element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void push_back (detail::moved_object<T> x)
- { this->insert(this->cend(), x); }
- #else
- void push_back (T &&x)
- { this->insert(this->cend(), detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Removes the first element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void pop_front()
- { this->erase(this->cbegin()); }
-
- //! <b>Effects</b>: Removes the last element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void pop_back()
- { const_iterator tmp = this->cend(); this->erase(--tmp); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference front()
- { return *this->begin(); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference front() const
- { return *this->begin(); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference back()
- { return *(--this->end()); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference back() const
- { return *(--this->end()); }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size, const T& x)
- {
- const_iterator iend = this->cend();
- size_type len = this->size();
-
- if(len > new_size){
- size_type to_erase = len - new_size;
- while(to_erase--){
- --iend;
- }
- this->erase(iend, this->cend());
- }
- else{
- this->priv_create_and_insert_nodes(iend, new_size - len, x);
- }
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size)
- {
- const_iterator iend = this->end();
- size_type len = this->size();
-
- if(len > new_size){
- size_type to_erase = len - new_size;
- const_iterator ifirst;
- if(to_erase < len/2u){
- ifirst = iend;
- while(to_erase--){
- --ifirst;
- }
- }
- else{
- ifirst = this->begin();
- size_type to_skip = len - to_erase;
- while(to_skip--){
- ++ifirst;
- }
- }
- this->erase(ifirst, iend);
- }
- else{
- this->priv_create_and_insert_nodes(this->cend(), new_size - len);
- }
- }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type()
- //! allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<ThisType> x)
- { this->swap(x.get()); }
- void swap(ThisType& x)
- #else
- void swap(ThisType &&x)
- #endif
- { AllocHolder::swap(x); }
-
- //! <b>Effects</b>: Makes *this contain the same elements as x.
- //!
- //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
- //! of each of x's elements.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in x.
- ThisType& operator=(const ThisType& x)
- {
- if (this != &x) {
- this->assign(x.begin(), x.end());
- }
- return *this;
- }
-
- //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
- //!
- //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
- //! before the function.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- ThisType& operator=(detail::moved_object<ThisType> mx)
- {
- this->clear();
- this->swap(mx.get());
- return *this;
- }
- #else
- ThisType& operator=(ThisType &&mx)
- {
- this->clear();
- this->swap(mx);
- return *this;
- }
- #endif
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts n copies of x before p.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- void insert(const_iterator p, size_type n, const T& x)
- { this->priv_create_and_insert_nodes(p, n, x); }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
- //!
- //! <b>Throws</b>: If memory allocation throws, T's constructor from a
- //! dereferenced InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
- template <class InpIt>
- void insert(const_iterator p, InpIt first, InpIt last)
- {
- const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(p, first, last, Result());
- }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of x before p.
- //!
- //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- iterator insert(const_iterator p, const T& x)
- {
- NodePtr tmp = AllocHolder::create_node(x);
- return iterator(this->icont().insert(p.get(), *tmp));
- }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator p, detail::moved_object<T> x)
- {
- NodePtr tmp = AllocHolder::create_node(x);
- return iterator(this->icont().insert(p.get(), *tmp));
- }
- #else
- iterator insert(const_iterator p, T &&x)
- {
- NodePtr tmp = AllocHolder::create_node(detail::move_impl(x));
- return iterator(this->icont().insert(p.get(), *tmp));
- }
- #endif
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the end of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- void emplace_back(Args&&... args)
- {
- this->emplace(this->cend(), detail::forward_impl<Args>(args)...);
- }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the beginning of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- void emplace_front(Args&&... args)
- {
- this->emplace(this->cbegin(), detail::forward_impl<Args>(args)...);
- }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... before p.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
- {
- typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
- new ((void*)detail::get_pointer(d.get())) Node(detail::forward_impl<Args>(args)...);
- NodePtr node = d.get();
- d.release();
- return iterator(this->icont().insert(p.get(), *node));
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //0 args
- void emplace_back()
- { this->emplace(this->cend()); }
-
- void emplace_front()
- { this->emplace(this->cbegin()); }
-
- iterator emplace(const_iterator p)
- {
- typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
- new ((void*)detail::get_pointer(d.get())) Node();
- NodePtr node = d.get();
- d.release();
- return iterator(this->icont().insert(p.get(), *node));
- }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cend(), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { this->emplace(this->cbegin(), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));} \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
- new ((void*)detail::get_pointer(d.get())) \
- Node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- NodePtr node = d.get(); \
- d.release(); \
- return iterator(this->icont().insert(p.get(), *node)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Erases the element at p p.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- iterator erase(const_iterator p)
- { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
-
- //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
- //!
- //! <b>Effects</b>: Erases the elements pointed by [first, last).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the distance between first and last.
- iterator erase(const_iterator first, const_iterator last)
- { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
-
- //! <b>Effects</b>: Assigns the n copies of val to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- void assign(size_type n, const T& val)
- { this->priv_fill_assign(n, val); }
-
- //! <b>Effects</b>: Assigns the the range [first, last) to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's constructor from dereferencing InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- template <class InpIt>
- void assign(InpIt first, InpIt last)
- {
- const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
- }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
- //!
- //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
- //! the element pointed by p. No destructors or copy constructors are called.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
- //! this list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(iterator p, detail::moved_object<ThisType> x)
- { this->splice(p, x.get()); }
- void splice(iterator p, ThisType& x)
- #else
- void splice(iterator p, ThisType&& x)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice(p.get(), x.icont());
- }
- else{
- throw std::runtime_error("list::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. i must point to an element contained in list x.
- //!
- //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
- //! If p == i or p == ++i, this function is a null operation.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator i)
- { this->splice(p, x.get(), i); }
- void splice(const_iterator p, ThisType &x, const_iterator i)
- #else
- void splice(const_iterator p, ThisType &&x, const_iterator i)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice(p.get(), x.icont(), i.get());
- }
- else{
- throw std::runtime_error("list::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. first and last must point to elements contained in list x.
- //!
- //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Linear to the number of elements transferred.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator first, const_iterator last)
- { this->splice(p, x.get(), first, last); }
- void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last)
- #else
- void splice(const_iterator p, ThisType &&x, const_iterator first, const_iterator last)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice(p.get(), x.icont(), first.get(), last.get());
- }
- else{
- throw std::runtime_error("list::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last)
- //!
- //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator first, const_iterator last, size_type n)
- { this->splice(p, x.get(), first, last, n); }
- void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n)
- #else
- void splice(const_iterator p, ThisType &&x, const_iterator first, const_iterator last, size_type n)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
- }
- else{
- throw std::runtime_error("list::splice called with unequal allocators");
- }
- }
-
- //! <b>Effects</b>: Reverses the order of elements in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time.
- //!
- //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
- { this->icont().reverse(); }
-
- //! <b>Effects</b>: Removes all the elements that compare equal to value.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- void remove(const T& value)
- { remove_if(equal_to_value(value)); }
-
- //! <b>Effects</b>: Removes all the elements for which a specified
- //! predicate is satisfied.
- //!
- //! <b>Throws</b>: If pred throws.
- //!
- //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- template <class Pred>
- void remove_if(Pred pred)
- {
- typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
- }
-
- //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
- //! elements that are equal from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- void unique()
- { this->unique(value_equal()); }
-
- //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
- //! elements that satisfy some binary predicate from the list.
- //!
- //! <b>Throws</b>: If pred throws.
- //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- template <class BinaryPredicate>
- void unique(BinaryPredicate binary_pred)
- {
- typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
- this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
- }
-
- //! <b>Requires</b>: The lists x and *this must be distinct.
- //!
- //! <b>Effects</b>: This function removes all of x's elements and inserts them
- //! in order into *this according to std::less<value_type>. The merge is stable;
- //! that is, if an element from *this is equivalent to one from x, then the element
- //! from *this will precede the one from x.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time: it performs at most
- //! size() + x.size() - 1 comparisons.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void merge(detail::moved_object<list<T, A> > x)
- { this->merge(x.get()); }
- void merge(list<T, A>& x)
- #else
- void merge(list<T, A>&& x)
- #endif
- { this->merge(x, value_less()); }
-
- //! <b>Requires</b>: p must be a comparison function that induces a strict weak
- //! ordering and both *this and x must be sorted according to that ordering
- //! The lists x and *this must be distinct.
- //!
- //! <b>Effects</b>: This function removes all of x's elements and inserts them
- //! in order into *this. The merge is stable; that is, if an element from *this is
- //! equivalent to one from x, then the element from *this will precede the one from x.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time: it performs at most
- //! size() + x.size() - 1 comparisons.
- //!
- //! <b>Note</b>: Iterators and references to *this are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- template <class StrictWeakOrdering>
- void merge(detail::moved_object<list<T, A> > x, StrictWeakOrdering comp)
- { this->merge(x.get(), comp); }
- template <class StrictWeakOrdering>
- void merge(list<T, A>& x, StrictWeakOrdering comp)
- #else
- template <class StrictWeakOrdering>
- void merge(list<T, A>&& x, StrictWeakOrdering comp)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
- else{
- throw std::runtime_error("list::merge called with unequal allocators");
- }
- }
-
- //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
- //! The sort is stable, that is, the relative order of equivalent elements is preserved.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Notes</b>: Iterators and references are not invalidated.
- //!
- //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
- //! is the list's size.
- void sort()
- { this->sort(value_less()); }
-
- //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
- //! The sort is stable, that is, the relative order of equivalent elements is preserved.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Notes</b>: Iterators and references are not invalidated.
- //!
- //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
- //! is the list's size.
- template <class StrictWeakOrdering>
- void sort(StrictWeakOrdering comp)
- {
- // nothing if the list has length 0 or 1.
- if (this->size() < 2)
- return;
- this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
-
- /// @cond
- private:
-
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, InpIterator beg, InpIterator end)
- {
- typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(pos, beg, end, alloc_version(), ItCat());
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
- {
- for (; beg != end; ++beg){
- this->icont().insert(pos.get(), *this->create_node_from_it(beg));
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag());
- }
-
- class insertion_functor;
- friend class insertion_functor;
-
- class insertion_functor
- {
- Icont &icont_;
- typename Icont::const_iterator pos_;
-
- public:
- insertion_functor(Icont &icont, typename Icont::const_iterator pos)
- : icont_(icont), pos_(pos)
- {}
-
- void operator()(Node &n)
- { this->icont_.insert(pos_, n); }
- };
-
-
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
- {
- if(beg != end){
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
- }
- }
-
- //Default constructed version
- void priv_create_and_insert_nodes(const_iterator pos, size_type n)
- {
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- this->priv_create_and_insert_nodes(pos, default_iterator(n), default_iterator());
- }
-
- //Copy constructed version
- void priv_create_and_insert_nodes(const_iterator pos, size_type n, const T& x)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->priv_create_and_insert_nodes(pos, cvalue_iterator(x, n), cvalue_iterator());
- }
-
- //Dispatch to detect iterator range or integer overloads
- template <class InputIter>
- void priv_insert_dispatch(const_iterator p,
- InputIter first, InputIter last,
- detail::false_)
- { this->priv_create_and_insert_nodes(p, first, last); }
-
- template<class Integer>
- void priv_insert_dispatch(const_iterator p, Integer n, Integer x, detail::true_)
- { this->insert(p, (size_type)n, x); }
-
- void priv_fill_assign(size_type n, const T& val)
- {
- iterator i = this->begin(), iend = this->end();
-
- for ( ; i != iend && n > 0; ++i, --n)
- *i = val;
- if (n > 0){
- this->priv_create_and_insert_nodes(this->cend(), n, val);
- }
- else{
- this->erase(i, cend());
- }
- }
-
- template <class Integer>
- void priv_assign_dispatch(Integer n, Integer val, detail::true_)
- { this->priv_fill_assign((size_type) n, (T) val); }
-
- template <class InputIter>
- void priv_assign_dispatch(InputIter first2, InputIter last2, detail::false_)
- {
- iterator first1 = this->begin();
- iterator last1 = this->end();
- for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
- *first1 = *first2;
- if (first2 == last2)
- this->erase(first1, last1);
- else{
- this->priv_create_and_insert_nodes(last1, first2, last2);
- }
- }
-
- //Functors for member algorithm defaults
- struct value_less
- {
- bool operator()(const value_type &a, const value_type &b) const
- { return a < b; }
- };
-
- struct value_equal
- {
- bool operator()(const value_type &a, const value_type &b) const
- { return a == b; }
- };
- /// @endcond
-
-};
-
-template <class T, class A>
-inline bool operator==(const list<T,A>& x, const list<T,A>& y)
-{
- if(x.size() != y.size()){
- return false;
- }
- typedef typename list<T,A>::const_iterator const_iterator;
- const_iterator end1 = x.end();
-
- const_iterator i1 = x.begin();
- const_iterator i2 = y.begin();
- while (i1 != end1 && *i1 == *i2) {
- ++i1;
- ++i2;
- }
- return i1 == end1;
-}
-
-template <class T, class A>
-inline bool operator<(const list<T,A>& x,
- const list<T,A>& y)
-{
- return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
-
-template <class T, class A>
-inline bool operator!=(const list<T,A>& x, const list<T,A>& y)
-{
- return !(x == y);
-}
-
-template <class T, class A>
-inline bool operator>(const list<T,A>& x, const list<T,A>& y)
-{
- return y < x;
-}
-
-template <class T, class A>
-inline bool operator<=(const list<T,A>& x, const list<T,A>& y)
-{
- return !(y < x);
-}
-
-template <class T, class A>
-inline bool operator>=(const list<T,A>& x, const list<T,A>& y)
-{
- return !(x < y);
-}
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class A>
-inline void swap(list<T, A>& x, list<T, A>& y)
-{
- x.swap(y);
-}
-
-template <class T, class A>
-inline void swap(detail::moved_object<list<T, A> >& x, list<T, A> y)
-{
- x.get().swap(y);
-}
-
-template <class T, class A>
-inline void swap(list<T, A>& x, detail::moved_object<list<T, A> > y)
-{
- x.swap(y.get());
-}
-#else
-template <class T, class A>
-inline void swap(list<T, A> &&x, list<T, A> &&y)
-{
- x.swap(y);
-}
-
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class A>
-struct is_movable<list<T, A> >
-{
- enum { value = true };
-};
-
-//!This class is movable
-template <class T, class VoidPointer>
-struct is_movable<detail::list_node<T, VoidPointer> >
-{
- enum { value = true };
-};
-/*
-//!This class is movable
-template <class A>
-struct is_movable<detail::list_alloc<A> >
-{
- enum { value = true };
-};
-*/
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class A>
-struct has_trivial_destructor_after_move<list<T, A> >
-{
- enum { value = has_trivial_destructor<A>::value };
-};
-/// @endcond
+using boost::interprocess_container::list;
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif // BOOST_INTERPROCESS_LIST_HPP_
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_LIST_HPP
+
Modified: trunk/boost/interprocess/containers/map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/map.hpp (original)
+++ trunk/boost/interprocess/containers/map.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,1313 +1,32 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_map/stl_multimap files. Modified by Ion Gaztanaga.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-/*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef BOOST_INTERPROCESS_MAP_HPP
-#define BOOST_INTERPROCESS_MAP_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_MAP_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <utility>
-#include <functional>
-#include <memory>
-#include <stdexcept>
-#include <boost/interprocess/containers/detail/tree.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/move.hpp>
-
-namespace boost { namespace interprocess {
-
-/// @cond
-// Forward declarations of operators == and <, needed for friend declarations.
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y);
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y);
-/// @endcond
-
-//! A map is a kind of associative container that supports unique keys (contains at
-//! most one of each key value) and provides for fast retrieval of values of another
-//! type T based on the keys. The map class supports bidirectional iterators.
-//!
-//! A map satisfies all of the requirements of a container and of a reversible
-//! container and of an associative container. For a
-//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
-//!
-//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
-//!
-//! Alloc is the allocator to allocate the value_types
-//! (e.g. <i>boost::interprocess:allocator< std::pair<const Key, T></i>).
-template <class Key, class T, class Pred, class Alloc>
-class map
-{
- /// @cond
- private:
- typedef detail::rbtree<Key,
- std::pair<const Key, T>,
- detail::select1st< std::pair<const Key, T> >,
- Pred,
- Alloc> tree_t;
- tree_t m_tree; // red-black tree representing map
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef T mapped_type;
- typedef Pred key_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- /// @cond
- class value_compare_impl
- : public Pred,
- public std::binary_function<value_type, value_type, bool>
- {
- friend class map<Key,T,Pred,Alloc>;
- protected :
- value_compare_impl(const Pred &c) : Pred(c) {}
- public:
- bool operator()(const value_type& x, const value_type& y) const {
- return Pred::operator()(x.first, y.first);
- }
- };
- /// @endcond
- typedef value_compare_impl value_compare;
-
- //! <b>Effects</b>: Constructs an empty map using the specified comparison object
- //! and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit map(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(comp, a)
- {}
-
- //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, true)
- {}
-
- //! <b>Effects</b>: Copy constructs a map.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- map(const map<Key,T,Pred,Alloc>& x)
- : m_tree(x.m_tree)
- {}
-
- //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- map(detail::moved_object<map<Key,T,Pred,Alloc> > x)
- : m_tree(detail::move_impl(x.get().m_tree))
- {}
- #else
- map(map<Key,T,Pred,Alloc> &&x)
- : m_tree(detail::move_impl(x.m_tree))
- {}
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- map<Key,T,Pred,Alloc>& operator=(const map<Key, T, Pred, Alloc>& x)
- { m_tree = x.m_tree; return *this; }
-
- //! <b>Effects</b>: this->swap(x.get()).
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- map<Key,T,Pred,Alloc>& operator=(detail::moved_object<map<Key,T,Pred,Alloc> > x)
- { m_tree = detail::move_impl(x.get().m_tree); return *this; }
- #else
- map<Key,T,Pred,Alloc>& operator=(map<Key,T,Pred,Alloc> &&x)
- { m_tree = detail::move_impl(x.m_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return m_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return value_compare(m_tree.key_comp()); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return m_tree.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return m_tree.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return m_tree.get_stored_allocator(); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_tree.max_size(); }
-
- //! Effects: If there is no key equivalent to x in the map, inserts
- //! value_type(x, T()) into the map.
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
- T& operator[](const key_type& k)
- {
- //we can optimize this
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first)){
- value_type val(k, detail::move_impl(T()));
- i = insert(i, detail::move_impl(val));
- }
- return (*i).second;
- }
-
- //! Effects: If there is no key equivalent to x in the map, inserts
- //! value_type(detail::move_impl(x), T()) into the map (the key is move-constructed)
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- T& operator[](detail::moved_object<key_type> mk)
- {
- key_type &k = mk.get();
- //we can optimize this
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first)){
- value_type val(k, detail::move_impl(T()));
- i = insert(i, detail::move_impl(val));
- }
- return (*i).second;
- }
- #else
- T& operator[](key_type &&mk)
- {
- key_type &k = mk;
- //we can optimize this
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first)){
- value_type val(detail::move_impl(k), detail::move_impl(T()));
- i = insert(i, detail::move_impl(val));
- }
- return (*i).second;
- }
- #endif
-
- //! Returns: A reference to the element whose key is equivalent to x.
- //! Throws: An exception object of type out_of_range if no such element is present.
- //! Complexity: logarithmic.
- T& at(const key_type& k)
- {
- iterator i = this->find(k);
- if(i == this->end()){
- throw std::out_of_range("key not found");
- }
- return i->second;
- }
-
- //! Returns: A reference to the element whose key is equivalent to x.
- //! Throws: An exception object of type out_of_range if no such element is present.
- //! Complexity: logarithmic.
- const T& at(const key_type& k) const
- {
- const_iterator i = this->find(k);
- if(i == this->end()){
- throw std::out_of_range("key not found");
- }
- return i->second;
- }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<map> x)
- { this->swap(x.get()); }
- void swap(map& x)
- #else
- void swap(map &&x)
- #endif
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Inserts x if and only if there is no element in the container
- //! with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- std::pair<iterator,bool> insert(const value_type& x)
- { return m_tree.insert_unique(x); }
-
- //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
- //! there is no element in the container with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- std::pair<iterator,bool> insert(const std::pair<key_type, mapped_type>& x)
- { return m_tree.insert_unique(x); }
-
- //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
- //! only if there is no element in the container with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- std::pair<iterator,bool> insert(detail::moved_object<std::pair<key_type, mapped_type> > x)
- { return m_tree.insert_unique(x); }
- #else
- std::pair<iterator,bool> insert(std::pair<key_type, mapped_type> &&x)
- { return m_tree.insert_unique(detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Move constructs a new value from x if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
- { return m_tree.insert_unique(x); }
- #else
- std::pair<iterator,bool> insert(value_type &&x)
- { return m_tree.insert_unique(detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- iterator insert(iterator position, const value_type& x)
- { return m_tree.insert_unique(position, x); }
-
- //! <b>Effects</b>: Move constructs a new value from x if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(iterator position, detail::moved_object<std::pair<key_type, mapped_type> > x)
- { return m_tree.insert_unique(position, x); }
- #else
- iterator insert(iterator position, std::pair<key_type, mapped_type> &&x)
- { return m_tree.insert_unique(position, detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator insert(iterator position, const std::pair<key_type, mapped_type>& x)
- { return m_tree.insert_unique(position, x); }
-
- //! <b>Effects</b>: Inserts an element move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(iterator position, detail::moved_object<value_type> x)
- { return m_tree.insert_unique(position, x); }
- #else
- iterator insert(iterator position, value_type &&x)
- { return m_tree.insert_unique(position, detail::move_impl(x)); }
- #endif
-
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) if and only
- //! if there is no element with key equivalent to the key of that element.
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_tree.insert_unique(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container if and only if there is
- //! no element in the container with an equivalent key.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return m_tree.emplace_unique(detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container if and only if there is
- //! no element in the container with an equivalent key.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return m_tree.emplace_hint_unique(hint, detail::forward_impl<Args>(args)...); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return m_tree.emplace_unique(); }
-
- iterator emplace_hint(const_iterator hint)
- { return m_tree.emplace_hint_unique(hint); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));}\
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by position.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator position)
- { return m_tree.erase(position); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
- { return m_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
- { return m_tree.erase(first, last); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_tree.clear(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: A const_iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return m_tree.upper_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return m_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
- { return m_tree.equal_range(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
- { return m_tree.equal_range(x); }
-
- /// @cond
- template <class K1, class T1, class C1, class A1>
- friend bool operator== (const map<K1, T1, C1, A1>&,
- const map<K1, T1, C1, A1>&);
- template <class K1, class T1, class C1, class A1>
- friend bool operator< (const map<K1, T1, C1, A1>&,
- const map<K1, T1, C1, A1>&);
- /// @endcond
-};
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y)
- { return x.m_tree == y.m_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y)
- { return x.m_tree < y.m_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator!=(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y)
- { return !(x == y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y)
- { return y < x; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<=(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y)
- { return !(y < x); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>=(const map<Key,T,Pred,Alloc>& x,
- const map<Key,T,Pred,Alloc>& y)
- { return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(map<Key,T,Pred,Alloc>& x, map<Key,T,Pred,Alloc>& y)
- { x.swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<map<Key,T,Pred,Alloc> > x, map<Key,T,Pred,Alloc>& y)
- { x.get().swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(map<Key,T,Pred,Alloc>& x, detail::moved_object<map<Key,T,Pred,Alloc> > y)
- { x.swap(y.get()); }
-#else
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(map<Key,T,Pred,Alloc>&&x, map<Key,T,Pred,Alloc>&&y)
- { x.swap(y); }
-#endif
-
-
-/// @cond
-
-//!This class is movable
-template <class T, class P, class A>
-struct is_movable<map<T, P, A> >
-{
- enum { value = true };
-};
-
-// Forward declaration of operators < and ==, needed for friend declaration.
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y);
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y);
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<map<K, T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-/// @endcond
-
-//! A multimap is a kind of associative container that supports equivalent keys
-//! (possibly containing multiple copies of the same key value) and provides for
-//! fast retrieval of values of another type T based on the keys. The multimap class
-//! supports bidirectional iterators.
-//!
-//! A multimap satisfies all of the requirements of a container and of a reversible
-//! container and of an associative container. For a
-//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
-//!
-//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
-//!
-//! Alloc is the allocator to allocate the value_types
-//!(e.g. <i>boost::interprocess:allocator< std::pair<<b>const</b> Key, T></i>).
-template <class Key, class T, class Pred, class Alloc>
-class multimap
-{
- /// @cond
- private:
- typedef detail::rbtree<Key,
- std::pair<const Key, T>,
- detail::select1st< std::pair<const Key, T> >,
- Pred,
- Alloc> tree_t;
- tree_t m_tree; // red-black tree representing map
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef T mapped_type;
- typedef Pred key_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- /// @cond
- class value_compare_impl
- : public Pred,
- public std::binary_function<value_type, value_type, bool>
- {
- friend class multimap<Key,T,Pred,Alloc>;
- protected :
- value_compare_impl(const Pred &c) : Pred(c) {}
- public:
- bool operator()(const value_type& x, const value_type& y) const {
- return Pred::operator()(x.first, y.first);
- }
- };
- /// @endcond
- typedef value_compare_impl value_compare;
-
- //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
- //! object and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit multimap(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(comp, a)
- {}
-
- //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
- //! and allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- multimap(InputIterator first, InputIterator last,
- const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, false)
- {}
-
- //! <b>Effects</b>: Copy constructs a multimap.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- multimap(const multimap<Key,T,Pred,Alloc>& x)
- : m_tree(x.m_tree)
- {}
-
- //! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- multimap(detail::moved_object<multimap<Key,T,Pred,Alloc> > x)
- : m_tree(detail::move_impl(x.get().m_tree))
- {}
- #else
- multimap(multimap<Key,T,Pred,Alloc> && x)
- : m_tree(detail::move_impl(x.m_tree))
- {}
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- multimap<Key,T,Pred,Alloc>&
- operator=(const multimap<Key,T,Pred,Alloc>& x)
- { m_tree = x.m_tree; return *this; }
-
- //! <b>Effects</b>: this->swap(x.get()).
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- multimap<Key,T,Pred,Alloc>& operator=(detail::moved_object<multimap<Key,T,Pred,Alloc> > x)
- { m_tree = detail::move_impl(x.get().m_tree); return *this; }
- #else
- multimap<Key,T,Pred,Alloc>& operator=(multimap<Key,T,Pred,Alloc> && x)
- { m_tree = detail::move_impl(x.m_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return m_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return value_compare(m_tree.key_comp()); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return m_tree.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return m_tree.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return m_tree.get_stored_allocator(); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_tree.max_size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<multimap> x)
- { this->swap(x.get()); }
- void swap(multimap& x)
- #else
- void swap(multimap &&x)
- #endif
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator insert(const value_type& x)
- { return m_tree.insert_equal(x); }
-
- //! <b>Effects</b>: Inserts a new value constructed from x and returns
- //! the iterator pointing to the newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator insert(const std::pair<key_type, mapped_type>& x)
- { return m_tree.insert_equal(x); }
-
- //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
- //! the iterator pointing to the newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(detail::moved_object<std::pair<key_type, mapped_type> > x)
- { return m_tree.insert_equal(x); }
- #else
- iterator insert(std::pair<key_type, mapped_type> && x)
- { return m_tree.insert_equal(detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- iterator insert(iterator position, const value_type& x)
- { return m_tree.insert_equal(position, x); }
+#include <boost/interprocess/containers/container/map.hpp>
- //! <b>Effects</b>: Inserts a new value constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- iterator insert(iterator position, const std::pair<key_type, mapped_type>& x)
- { return m_tree.insert_equal(position, x); }
+namespace boost {
+namespace interprocess {
- //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(iterator position, detail::moved_object<std::pair<key_type, mapped_type> > x)
- { return m_tree.insert_equal(position, x); }
- #else
- iterator insert(iterator position, std::pair<key_type, mapped_type> && x)
- { return m_tree.insert_equal(position, detail::move_impl(x)); }
- #endif
+using boost::interprocess_container::map;
+using boost::interprocess_container::multimap;
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) .
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_tree.insert_equal(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return m_tree.emplace_equal(detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return m_tree.emplace_hint_equal(hint, detail::forward_impl<Args>(args)...); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return m_tree.emplace_equal(); }
-
- iterator emplace_hint(const_iterator hint)
- { return m_tree.emplace_hint_equal(hint); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); }\
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by position.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator position)
- { return m_tree.erase(position); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
- { return m_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
- { return m_tree.erase(first, last); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_tree.clear(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: A const iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_tree.count(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- {return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return m_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator> equal_range(const key_type& x)
- { return m_tree.equal_range(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return m_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator,const_iterator>
- equal_range(const key_type& x) const
- { return m_tree.equal_range(x); }
-
- /// @cond
- template <class K1, class T1, class C1, class A1>
- friend bool operator== (const multimap<K1, T1, C1, A1>& x,
- const multimap<K1, T1, C1, A1>& y);
-
- template <class K1, class T1, class C1, class A1>
- friend bool operator< (const multimap<K1, T1, C1, A1>& x,
- const multimap<K1, T1, C1, A1>& y);
- /// @endcond
-};
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator==(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y)
-{ return x.m_tree == y.m_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y)
-{ return x.m_tree < y.m_tree; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator!=(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y)
-{ return !(x == y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y)
-{ return y < x; }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator<=(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y)
-{ return !(y < x); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline bool operator>=(const multimap<Key,T,Pred,Alloc>& x,
- const multimap<Key,T,Pred,Alloc>& y)
-{ return !(x < y); }
-
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(multimap<Key,T,Pred,Alloc>& x, multimap<Key,T,Pred,Alloc>& y)
-{ x.swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<multimap<Key,T,Pred,Alloc> > x, multimap<Key,T,Pred,Alloc>& y)
-{ x.get().swap(y); }
-
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(multimap<Key,T,Pred,Alloc>& x, detail::moved_object<multimap<Key,T,Pred,Alloc> > y)
-{ x.swap(y.get()); }
-#else
-template <class Key, class T, class Pred, class Alloc>
-inline void swap(multimap<Key,T,Pred,Alloc>&&x, multimap<Key,T,Pred,Alloc>&&y)
-{ x.swap(y); }
-#endif
-
-/// @cond
-template <class T, class P, class A>
-struct is_movable<multimap<T, P, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<multimap<K, T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-/// @endcond
-
-}} //namespace boost { namespace interprocess {
+} //namespace interprocess {
+} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_MAP_HPP */
-
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_MAP_HPP
Added: trunk/boost/interprocess/containers/pair.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/pair.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_CONTAINERS_PAIR_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_PAIR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/pair.hpp>
+
+namespace boost {
+namespace interprocess {
+
+using boost::interprocess_container::containers_detail::pair;
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_PAIR_HPP
+
Modified: trunk/boost/interprocess/containers/set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/set.hpp (original)
+++ trunk/boost/interprocess/containers/set.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,1186 +1,32 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_set/stl_multiset files. Modified by Ion Gaztanaga 2004.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-/*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef BOOST_INTERPROCESS_SET_HPP
-#define BOOST_INTERPROCESS_SET_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_SET_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-
-#include <utility>
-#include <functional>
-#include <memory>
-
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/containers/detail/tree.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-#include <boost/interprocess/detail/preprocessor.hpp>
-#endif
-
-namespace boost { namespace interprocess {
-
-/// @cond
-// Forward declarations of operators < and ==, needed for friend declaration.
-template <class T, class Pred, class Alloc>
-inline bool operator==(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y);
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y);
-/// @endcond
-
-//! A set is a kind of associative container that supports unique keys (contains at
-//! most one of each key value) and provides for fast retrieval of the keys themselves.
-//! Class set supports bidirectional iterators.
-//!
-//! A set satisfies all of the requirements of a container and of a reversible container
-//! , and of an associative container. A set also provides most operations described in
-//! for unique keys.
-template <class T, class Pred, class Alloc>
-class set
-{
- /// @cond
- private:
- typedef detail::rbtree<T, T,
- detail::identity<T>, Pred, Alloc> tree_t;
- tree_t m_tree; // red-black tree representing set
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef Pred key_compare;
- typedef Pred value_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- //! <b>Effects</b>: Constructs an empty set using the specified comparison object
- //! and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit set(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(comp, a)
- {}
-
- //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
- //! allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, true)
- {}
-
- //! <b>Effects</b>: Copy constructs a set.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- set(const set<T,Pred,Alloc>& x)
- : m_tree(x.m_tree)
- {}
-
- //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- set(detail::moved_object<set<T,Pred,Alloc> > x)
- : m_tree(detail::move_impl(x.get().m_tree))
- {}
- #else
- set(set<T,Pred,Alloc> &&x)
- : m_tree(detail::move_impl(x.m_tree))
- {}
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- set<T,Pred,Alloc>& operator=(const set<T, Pred, Alloc>& x)
- { m_tree = x.m_tree; return *this; }
-
- //! <b>Effects</b>: this->swap(x.get()).
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- set<T,Pred,Alloc>& operator=(detail::moved_object<set<T, Pred, Alloc> > x)
- { m_tree = detail::move_impl(x.get().m_tree); return *this; }
- #else
- set<T,Pred,Alloc>& operator=(set<T, Pred, Alloc> &&x)
- { m_tree = detail::move_impl(x.m_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return m_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return m_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return m_tree.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return m_tree.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return m_tree.get_stored_allocator(); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant
- iterator begin()
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return m_tree.cbegin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return m_tree.cend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return m_tree.crbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return m_tree.crend(); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_tree.max_size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<set> x)
- { this->swap(x.get()); }
- void swap(set& x)
- #else
- void swap(set &&x)
- #endif
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Inserts x if and only if there is no element in the container
- //! with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- std::pair<iterator,bool> insert(const value_type& x)
- { return m_tree.insert_unique(x); }
-
- //! <b>Effects</b>: Move constructs a new value from x if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //!
- //! <b>Returns</b>: The bool component of the returned pair is true if and only
- //! if the insertion takes place, and the iterator component of the pair
- //! points to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
- { return m_tree.insert_unique(x); }
- #else
- std::pair<iterator,bool> insert(value_type &&x)
- { return m_tree.insert_unique(detail::move_impl(x)); }
- #endif
-
- //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
- //! no element in the container with key equivalent to the key of x.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- iterator insert(const_iterator p, const value_type& x)
- { return m_tree.insert_unique(p, x); }
-
- //! <b>Effects</b>: Inserts an element move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator p, detail::moved_object<value_type> x)
- { return m_tree.insert_unique(p, x); }
- #else
- iterator insert(const_iterator p, value_type &&x)
- { return m_tree.insert_unique(p, detail::move_impl(x)); }
- #endif
-
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) if and only
- //! if there is no element with key equivalent to the key of that element.
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_tree.insert_unique(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... if and only if there is
- //! no element in the container with equivalent value.
- //! and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Logarithmic.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return m_tree.emplace_unique(detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... if and only if there is
- //! no element in the container with equivalent value.
- //! p is a hint pointing to where the insert
- //! should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return m_tree.emplace_hint_unique(hint, detail::forward_impl<Args>(args)...); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return m_tree.emplace_unique(); }
-
- iterator emplace_hint(const_iterator hint)
- { return m_tree.emplace_hint_unique(hint); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));}\
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by p.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator p)
- { return m_tree.erase(p); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
- { return m_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
- { return m_tree.erase(first, last); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_tree.clear(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: A const_iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return m_tree.upper_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return m_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator>
- equal_range(const key_type& x)
- { return m_tree.equal_range(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& x) const
- { return m_tree.equal_range(x); }
-
- /// @cond
- template <class K1, class C1, class A1>
- friend bool operator== (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
-
- template <class K1, class C1, class A1>
- friend bool operator< (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
- /// @endcond
-};
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y)
-{ return x.m_tree == y.m_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y)
-{ return x.m_tree < y.m_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator!=(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y)
-{ return !(x == y); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y)
-{ return y < x; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<=(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y)
-{ return !(y < x); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>=(const set<T,Pred,Alloc>& x,
- const set<T,Pred,Alloc>& y)
-{ return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class Pred, class Alloc>
-inline void swap(set<T,Pred,Alloc>& x, set<T,Pred,Alloc>& y)
-{ x.swap(y); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(set<T,Pred,Alloc>& x, detail::moved_object<set<T,Pred,Alloc> >& y)
-{ x.swap(y.get()); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<set<T,Pred,Alloc> >& y, set<T,Pred,Alloc>& x)
-{ y.swap(x.get()); }
-
-#else
-template <class T, class Pred, class Alloc>
-inline void swap(set<T,Pred,Alloc>&&x, set<T,Pred,Alloc>&&y)
-{ x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class P, class A>
-struct is_movable<set<T, P, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class C, class A>
-struct has_trivial_destructor_after_move<set<T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-
-// Forward declaration of operators < and ==, needed for friend declaration.
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y);
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y);
-/// @endcond
-
-//! A multiset is a kind of associative container that supports equivalent keys
-//! (possibly contains multiple copies of the same key value) and provides for
-//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
-//!
-//! A multiset satisfies all of the requirements of a container and of a reversible
-//! container, and of an associative container). multiset also provides most operations
-//! described for duplicate keys.
-template <class T, class Pred, class Alloc>
-class multiset
-{
- /// @cond
- private:
- typedef detail::rbtree<T, T,
- detail::identity<T>, Pred, Alloc> tree_t;
- tree_t m_tree; // red-black tree representing multiset
- /// @endcond
-
- public:
- // typedefs:
- typedef typename tree_t::key_type key_type;
- typedef typename tree_t::value_type value_type;
- typedef typename tree_t::pointer pointer;
- typedef typename tree_t::const_pointer const_pointer;
- typedef typename tree_t::reference reference;
- typedef typename tree_t::const_reference const_reference;
- typedef Pred key_compare;
- typedef Pred value_compare;
- typedef typename tree_t::iterator iterator;
- typedef typename tree_t::const_iterator const_iterator;
- typedef typename tree_t::reverse_iterator reverse_iterator;
- typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
- typedef typename tree_t::size_type size_type;
- typedef typename tree_t::difference_type difference_type;
- typedef typename tree_t::allocator_type allocator_type;
- typedef typename tree_t::stored_allocator_type stored_allocator_type;
-
- //! <b>Effects</b>: Constructs an empty multiset using the specified comparison
- //! object and allocator.
- //!
- //! <b>Complexity</b>: Constant.
- explicit multiset(const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(comp, a)
- {}
-
- //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object
- //! and allocator, and inserts elements from the range [first ,last ).
- //!
- //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
- //! comp and otherwise N logN, where N is last - first.
- template <class InputIterator>
- multiset(InputIterator first, InputIterator last,
- const Pred& comp = Pred(),
- const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, false)
- {}
-
- //! <b>Effects</b>: Copy constructs a multiset.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- multiset(const multiset<T,Pred,Alloc>& x)
- : m_tree(x.m_tree)
- {}
-
- //! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
- //!
- //! <b>Complexity</b>: Construct.
- //!
- //! <b>Postcondition</b>: x is emptied.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- multiset(detail::moved_object<multiset<T,Pred,Alloc> > x)
- : m_tree(detail::move_impl(x.get().m_tree))
- {}
- #else
- multiset(multiset<T,Pred,Alloc> &&x)
- : m_tree(detail::move_impl(x.m_tree))
- {}
- #endif
-
- //! <b>Effects</b>: Makes *this a copy of x.
- //!
- //! <b>Complexity</b>: Linear in x.size().
- multiset<T,Pred,Alloc>& operator=(const multiset<T,Pred,Alloc>& x)
- { m_tree = x.m_tree; return *this; }
-
- //! <b>Effects</b>: this->swap(x.get()).
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- multiset<T,Pred,Alloc>& operator=(detail::moved_object<multiset<T,Pred,Alloc> > x)
- { m_tree = detail::move_impl(x.get().m_tree); return *this; }
- #else
- multiset<T,Pred,Alloc>& operator=(multiset<T,Pred,Alloc> &&x)
- { m_tree = detail::move_impl(x.m_tree); return *this; }
- #endif
-
- //! <b>Effects</b>: Returns the comparison object out
- //! of which a was constructed.
- //!
- //! <b>Complexity</b>: Constant.
- key_compare key_comp() const
- { return m_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns an object of value_compare constructed out
- //! of the comparison object.
- //!
- //! <b>Complexity</b>: Constant.
- value_compare value_comp() const
- { return m_tree.key_comp(); }
-
- //! <b>Effects</b>: Returns a copy of the Allocator that
- //! was passed to the object's constructor.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return m_tree.get_allocator(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return m_tree.get_stored_allocator(); }
-
- stored_allocator_type &get_stored_allocator()
- { return m_tree.get_stored_allocator(); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return m_tree.begin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return m_tree.end(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return m_tree.rbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return m_tree.rend(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return m_tree.cbegin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return m_tree.cend(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return m_tree.crbegin(); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return m_tree.crend(); }
-
- //! <b>Effects</b>: Returns true if the container contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return m_tree.empty(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return m_tree.size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return m_tree.max_size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<multiset> x)
- { this->swap(x.get()); }
- void swap(multiset& x)
- #else
- void swap(multiset &&x)
- #endif
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator insert(const value_type& x)
- { return m_tree.insert_equal(x); }
-
- //! <b>Effects</b>: Inserts a copy of x in the container.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(detail::moved_object<value_type> x)
- { return m_tree.insert_equal(x); }
- #else
- iterator insert(value_type && x)
- { return m_tree.insert_equal(detail::move_impl(x)); }
- #endif
+#include <boost/interprocess/containers/container/set.hpp>
- //! <b>Effects</b>: Inserts a copy of x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- iterator insert(const_iterator p, const value_type& x)
- { return m_tree.insert_equal(p, x); }
+namespace boost {
+namespace interprocess {
- //! <b>Effects</b>: Inserts a value move constructed from x in the container.
- //! p is a hint pointing to where the insert should start to search.
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator p, detail::moved_object<value_type> x)
- { return m_tree.insert_equal(p, x); }
- #else
- iterator insert(const_iterator p, value_type && x)
- { return m_tree.insert_equal(p, detail::move_impl(x)); }
- #endif
+using boost::interprocess_container::set;
+using boost::interprocess_container::multiset;
- //! <b>Requires</b>: i, j are not iterators into *this.
- //!
- //! <b>Effects</b>: inserts each element from the range [i,j) .
- //!
- //! <b>Complexity</b>: N log(size()+N) (N is the distance from i to j)
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- { m_tree.insert_equal(first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... and returns the iterator pointing to the
- //! newly inserted element.
- //!
- //! <b>Complexity</b>: Logarithmic.
- template <class... Args>
- iterator emplace(Args&&... args)
- { return m_tree.emplace_equal(detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)...
- //!
- //! <b>Returns</b>: An iterator pointing to the element with key equivalent
- //! to the key of x.
- //!
- //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
- //! is inserted right before p.
- template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
- { return m_tree.emplace_hint_equal(hint, detail::forward_impl<Args>(args)...); }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- iterator emplace()
- { return m_tree.emplace_equal(); }
-
- iterator emplace_hint(const_iterator hint)
- { return m_tree.emplace_hint_equal(hint); }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); }\
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element pointed to by p.
- //!
- //! <b>Returns</b>: Returns an iterator pointing to the element immediately
- //! following q prior to the element being erased. If no such element exists,
- //! returns end().
- //!
- //! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator p)
- { return m_tree.erase(p); }
-
- //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
- //!
- //! <b>Returns</b>: Returns the number of erased elements.
- //!
- //! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
- { return m_tree.erase(x); }
-
- //! <b>Effects</b>: Erases all the elements in the range [first, last).
- //!
- //! <b>Returns</b>: Returns last.
- //!
- //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
- { return m_tree.erase(first, last); }
-
- //! <b>Effects</b>: erase(a.begin(),a.end()).
- //!
- //! <b>Postcondition</b>: size() == 0.
- //!
- //! <b>Complexity</b>: linear in size().
- void clear()
- { m_tree.clear(); }
-
- //! <b>Returns</b>: An iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- iterator find(const key_type& x)
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: A const iterator pointing to an element with the key
- //! equivalent to x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic.
- const_iterator find(const key_type& x) const
- { return m_tree.find(x); }
-
- //! <b>Returns</b>: The number of elements with key equivalent to x.
- //!
- //! <b>Complexity</b>: log(size())+count(k)
- size_type count(const key_type& x) const
- { return m_tree.count(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator lower_bound(const key_type& x)
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than k, or a.end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator lower_bound(const key_type& x) const
- { return m_tree.lower_bound(x); }
-
- //! <b>Returns</b>: An iterator pointing to the first element with key not less
- //! than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- iterator upper_bound(const key_type& x)
- { return m_tree.upper_bound(x); }
-
- //! <b>Returns</b>: A const iterator pointing to the first element with key not
- //! less than x, or end() if such an element is not found.
- //!
- //! <b>Complexity</b>: Logarithmic
- const_iterator upper_bound(const key_type& x) const
- { return m_tree.upper_bound(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<iterator,iterator>
- equal_range(const key_type& x)
- { return m_tree.equal_range(x); }
-
- //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
- //!
- //! <b>Complexity</b>: Logarithmic
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& x) const
- { return m_tree.equal_range(x); }
-
- /// @cond
- template <class K1, class C1, class A1>
- friend bool operator== (const multiset<K1,C1,A1>&,
- const multiset<K1,C1,A1>&);
- template <class K1, class C1, class A1>
- friend bool operator< (const multiset<K1,C1,A1>&,
- const multiset<K1,C1,A1>&);
- /// @endcond
-};
-
-template <class T, class Pred, class Alloc>
-inline bool operator==(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y)
-{ return x.m_tree == y.m_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y)
-{ return x.m_tree < y.m_tree; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator!=(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y)
-{ return !(x == y); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y)
-{ return y < x; }
-
-template <class T, class Pred, class Alloc>
-inline bool operator<=(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y)
-{ return !(y < x); }
-
-template <class T, class Pred, class Alloc>
-inline bool operator>=(const multiset<T,Pred,Alloc>& x,
- const multiset<T,Pred,Alloc>& y)
-{ return !(x < y); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class Pred, class Alloc>
-inline void swap(multiset<T,Pred,Alloc>& x, multiset<T,Pred,Alloc>& y)
-{ x.swap(y); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(multiset<T,Pred,Alloc>& x, detail::moved_object<multiset<T,Pred,Alloc> >& y)
-{ x.swap(y.get()); }
-
-template <class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<multiset<T,Pred,Alloc> >& y, multiset<T,Pred,Alloc>& x)
-{ y.swap(x.get()); }
-#else
-template <class T, class Pred, class Alloc>
-inline void swap(multiset<T,Pred,Alloc>&&x, multiset<T,Pred,Alloc>&&y)
-{ x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class P, class A>
-struct is_movable<multiset<T, P, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class C, class A>
-struct has_trivial_destructor_after_move<multiset<T, C, A> >
-{
- enum { value =
- has_trivial_destructor<A>::value &&
- has_trivial_destructor<C>::value };
-};
-/// @endcond
-
-}} //namespace boost { namespace interprocess {
+} //namespace interprocess {
+} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_SET_HPP */
-
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_SET_HPP
Modified: trunk/boost/interprocess/containers/slist.hpp
==============================================================================
--- trunk/boost/interprocess/containers/slist.hpp (original)
+++ trunk/boost/interprocess/containers/slist.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,1642 +1,31 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2008
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-/*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef BOOST_INTERPROCESS_SLIST_HPP
-#define BOOST_INTERPROCESS_SLIST_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_SLIST_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_SLIST_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
-#include <boost/intrusive/slist.hpp>
-
-
-#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-//Preprocessor library to emulate perfect forwarding
-#include <boost/interprocess/detail/preprocessor.hpp>
-#endif
-
-#include <iterator>
-#include <utility>
-#include <memory>
-#include <functional>
-#include <algorithm>
-
-namespace boost{ namespace interprocess{
-
-/// @cond
-
-namespace detail {
-
-template<class VoidPointer>
-struct slist_hook
-{
- typedef typename bi::make_slist_base_hook
- <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type type;
-};
-
-template <class T, class VoidPointer>
-struct slist_node
- : public slist_hook<VoidPointer>::type
-{
- #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- slist_node()
- : m_data()
- {}
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- slist_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #else //#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template<class ...Args>
- slist_node(Args &&...args)
- : m_data(detail::forward_impl<Args>(args)...)
- {}
- #endif//#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- T m_data;
-};
-
-template<class A>
-struct intrusive_slist_type
-{
- typedef typename A::value_type value_type;
- typedef typename detail::pointer_to_other
- <typename A::pointer, void>::type void_pointer;
- typedef typename detail::slist_node
- <value_type, void_pointer> node_type;
-
- typedef typename bi::make_slist
- <node_type
- ,bi::base_hook<typename slist_hook<void_pointer>::type>
- ,bi::constant_time_size<true>
- ,bi::size_type<typename A::size_type>
- >::type container_type;
- typedef container_type type ;
-};
-
-} //namespace detail {
-
-/// @endcond
-
-//! An slist is a singly linked list: a list where each element is linked to the next
-//! element, but not to the previous element. That is, it is a Sequence that
-//! supports forward but not backward traversal, and (amortized) constant time
-//! insertion and removal of elements. Slists, like lists, have the important
-//! property that insertion and splicing do not invalidate iterators to list elements,
-//! and that even removal invalidates only the iterators that point to the elements
-//! that are removed. The ordering of iterators may be changed (that is,
-//! slist<T>::iterator might have a different predecessor or successor after a list
-//! operation than it did before), but the iterators themselves will not be invalidated
-//! or made to point to different elements unless that invalidation or mutation is explicit.
-//!
-//! The main difference between slist and list is that list's iterators are bidirectional
-//! iterators, while slist's iterators are forward iterators. This means that slist is
-//! less versatile than list; frequently, however, bidirectional iterators are
-//! unnecessary. You should usually use slist unless you actually need the extra
-//! functionality of list, because singly linked lists are smaller and faster than double
-//! linked lists.
-//!
-//! Important performance note: like every other Sequence, slist defines the member
-//! functions insert and erase. Using these member functions carelessly, however, can
-//! result in disastrously slow programs. The problem is that insert's first argument is
-//! an iterator p, and that it inserts the new element(s) before p. This means that
-//! insert must find the iterator just before p; this is a constant-time operation
-//! for list, since list has bidirectional iterators, but for slist it must find that
-//! iterator by traversing the list from the beginning up to p. In other words:
-//! insert and erase are slow operations anywhere but near the beginning of the slist.
-//!
-//! Slist provides the member functions insert_after and erase_after, which are constant
-//! time operations: you should always use insert_after and erase_after whenever
-//! possible. If you find that insert_after and erase_after aren't adequate for your
-//! needs, and that you often need to use insert and erase in the middle of the list,
-//! then you should probably use list instead of slist.
-template <class T, class A>
-class slist
- : protected detail::node_alloc_holder
- <A, typename detail::intrusive_slist_type<A>::type>
-{
- /// @cond
- typedef typename
- detail::intrusive_slist_type<A>::type Icont;
- typedef detail::node_alloc_holder<A, Icont> AllocHolder;
- typedef typename AllocHolder::NodePtr NodePtr;
- typedef slist <T, A> ThisType;
- typedef typename AllocHolder::NodeAlloc NodeAlloc;
- typedef typename AllocHolder::ValAlloc ValAlloc;
- typedef typename AllocHolder::Node Node;
- typedef detail::allocator_destroyer<NodeAlloc> Destroyer;
- typedef typename AllocHolder::allocator_v1 allocator_v1;
- typedef typename AllocHolder::allocator_v2 allocator_v2;
- typedef typename AllocHolder::alloc_version alloc_version;
-
- class equal_to_value
- {
- typedef typename AllocHolder::value_type value_type;
- const value_type &t_;
-
- public:
- equal_to_value(const value_type &t)
- : t_(t)
- {}
-
- bool operator()(const value_type &t)const
- { return t_ == t; }
- };
-
- template<class Pred>
- struct ValueCompareToNodeCompare
- : Pred
- {
- ValueCompareToNodeCompare(Pred pred)
- : Pred(pred)
- {}
-
- bool operator()(const Node &a, const Node &b) const
- { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
-
- bool operator()(const Node &a) const
- { return static_cast<const Pred&>(*this)(a.m_data); }
- };
- /// @endcond
- public:
- //! The type of object, T, stored in the list
- typedef T value_type;
- //! Pointer to T
- typedef typename A::pointer pointer;
- //! Const pointer to T
- typedef typename A::const_pointer const_pointer;
- //! Reference to T
- typedef typename A::reference reference;
- //! Const reference to T
- typedef typename A::const_reference const_reference;
- //! An unsigned integral type
- typedef typename A::size_type size_type;
- //! A signed integral type
- typedef typename A::difference_type difference_type;
- //! The allocator type
- typedef A allocator_type;
- //! The stored allocator type
- typedef NodeAlloc stored_allocator_type;
-
- /// @cond
- private:
- typedef difference_type list_difference_type;
- typedef pointer list_pointer;
- typedef const_pointer list_const_pointer;
- typedef reference list_reference;
- typedef const_reference list_const_reference;
- /// @endcond
-
- public:
- //! Const iterator used to iterate through a list.
- class const_iterator
- /// @cond
- : public std::iterator<std::forward_iterator_tag,
- value_type, list_difference_type,
- list_const_pointer, list_const_reference>
- {
-
- protected:
- typename Icont::iterator m_it;
- explicit const_iterator(typename Icont::iterator it) : m_it(it){}
- void prot_incr(){ ++m_it; }
-
- private:
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class slist<T, A>;
- typedef list_difference_type difference_type;
-
- //Constructors
- const_iterator()
- : m_it()
- {}
-
- //Pointer like operators
- const_reference operator*() const
- { return m_it->m_data; }
-
- const_pointer operator->() const
- { return const_pointer(&m_it->m_data); }
-
- //Increment / Decrement
- const_iterator& operator++()
- { prot_incr(); return *this; }
-
- const_iterator operator++(int)
- { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
-
- //Comparison operators
- bool operator== (const const_iterator& r) const
- { return m_it == r.m_it; }
-
- bool operator!= (const const_iterator& r) const
- { return m_it != r.m_it; }
- }
- /// @endcond
- ;
-
- //! Iterator used to iterate through a list
- class iterator
- /// @cond
- : public const_iterator
- {
-
- private:
- explicit iterator(typename Icont::iterator it)
- : const_iterator(it)
- {}
-
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class slist<T, A>;
- typedef list_pointer pointer;
- typedef list_reference reference;
-
- //Constructors
- iterator(){}
-
- //Pointer like operators
- reference operator*() const { return this->m_it->m_data; }
- pointer operator->() const { return pointer(&this->m_it->m_data); }
-
- //Increment / Decrement
- iterator& operator++()
- { this->prot_incr(); return *this; }
-
- iterator operator++(int)
- { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
- }
- /// @endcond
- ;
-
- public:
- //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- explicit slist(const allocator_type& a = allocator_type())
- : AllocHolder(a)
- {}
-
-// explicit slist(size_type n)
-// : AllocHolder(detail::move_impl(allocator_type()))
-// { this->resize(n); }
-
- //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
- //! and inserts n copies of value.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
- //! throws or T's default or copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- explicit slist(size_type n, const value_type& x = value_type(),
- const allocator_type& a = allocator_type())
- : AllocHolder(a)
- { this->priv_create_and_insert_nodes(this->before_begin(), n, x); }
-
- //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
- //! and inserts a copy of the range [first, last) in the list.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
- //! throws or T's constructor taking an dereferenced InIt throws.
- //!
- //! <b>Complexity</b>: Linear to the range [first, last).
- template <class InpIt>
- slist(InpIt first, InpIt last,
- const allocator_type& a = allocator_type())
- : AllocHolder(a)
- { this->insert_after(this->before_begin(), first, last); }
-
- //! <b>Effects</b>: Copy constructs a list.
- //!
- //! <b>Postcondition</b>: x == *this.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the elements x contains.
- slist(const slist& x)
- : AllocHolder(x)
- { this->insert_after(this->before_begin(), x.begin(), x.end()); }
-
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- slist(detail::moved_object<slist> x)
- : AllocHolder(detail::move_impl((AllocHolder&)x.get()))
- {}
- #else
- slist(slist &&x)
- : AllocHolder(detail::move_impl((AllocHolder&)x))
- {}
- #endif
-
- //! <b>Effects</b>: Makes *this contain the same elements as x.
- //!
- //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
- //! of each of x's elements.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in x.
- slist& operator= (const slist& x)
- {
- if (&x != this){
- this->assign(x.begin(), x.end());
- }
- return *this;
- }
-
- //! <b>Effects</b>: Makes *this contain the same elements as x.
- //!
- //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
- //! of each of x's elements.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in x.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- slist& operator= (detail::moved_object<slist> mx)
- {
- if (&mx.get() != this){
- this->clear();
- this->swap(mx.get());
- }
- return *this;
- }
- #else
- slist& operator= (slist && mx)
- {
- if (&mx != this){
- this->clear();
- this->swap(mx);
- }
- return *this;
- }
- #endif
-
- //! <b>Effects</b>: Destroys the list. All stored values are destroyed
- //! and used memory is deallocated.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements.
- ~slist()
- {} //AllocHolder clears the slist
-
- //! <b>Effects</b>: Returns a copy of the internal allocator.
- //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return allocator_type(this->node_alloc()); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return this->node_alloc(); }
-
- stored_allocator_type &get_stored_allocator()
- { return this->node_alloc(); }
-
- public:
-
- //! <b>Effects</b>: Assigns the n copies of val to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- void assign(size_type n, const T& val)
- { this->priv_fill_assign(n, val); }
-
- //! <b>Effects</b>: Assigns the range [first, last) to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's constructor from dereferencing InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- template <class InpIt>
- void assign(InpIt first, InpIt last)
- {
- const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
- }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return iterator(this->icont().begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return this->cbegin(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return iterator(this->icont().end()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return this->cend(); }
-
- //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
- //! when incremented, yields begin(). This iterator may be used
- //! as the argument toinsert_after, erase_after, etc.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator before_begin()
- { return iterator(end()); }
-
- //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
- //! that, when incremented, yields begin(). This iterator may be used
- //! as the argument toinsert_after, erase_after, etc.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator before_begin() const
- { return this->cbefore_begin(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return const_iterator(this->non_const_icont().begin()); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return const_iterator(this->non_const_icont().end()); }
-
- //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
- //! that, when incremented, yields begin(). This iterator may be used
- //! as the argument toinsert_after, erase_after, etc.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbefore_begin() const
- { return const_iterator(end()); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return this->icont().size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return AllocHolder::max_size(); }
-
- //! <b>Effects</b>: Returns true if the list contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->size(); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type()
- //! allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on *this and x.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<slist> x)
- { this->swap(x.get()); }
- void swap(slist& x)
- #else
- void swap(slist &&x)
- #endif
- { AllocHolder::swap(x); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference front()
- { return *this->begin(); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference front() const
- { return *this->begin(); }
-
- //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_front(const value_type& x)
- { this->icont().push_front(*this->create_node(x)); }
-
- //! <b>Effects</b>: Constructs a new element in the beginning of the list
- //! and moves the resources of t to this new element.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void push_front(detail::moved_object<T> x)
- { this->icont().push_front(*this->create_node(x)); }
- #else
- void push_front(T && x)
- { this->icont().push_front(*this->create_node(detail::move_impl(x))); }
- #endif
-
- //! <b>Effects</b>: Removes the first element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void pop_front()
- { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
-
- //! <b>Returns</b>: The iterator to the element before i in the sequence.
- //! Returns the end-iterator, if either i is the begin-iterator or the
- //! sequence is empty.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements before i.
- iterator previous(iterator p)
- { return iterator(this->icont().previous(p.get())); }
-
- //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
- //! Returns the end-const_iterator, if either i is the begin-const_iterator or
- //! the sequence is empty.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements before i.
- const_iterator previous(const_iterator p)
- { return const_iterator(this->icont().previous(p.get())); }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts a copy of the value after the p pointed
- //! by prev_p.
- //!
- //! <b>Returns</b>: An iterator to the inserted element.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references of
- //! previous values.
- iterator insert_after(const_iterator prev_pos, const value_type& x)
- { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
-
- //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts a move constructed copy object from the value after the
- //! p pointed by prev_pos.
- //!
- //! <b>Returns</b>: An iterator to the inserted element.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references of
- //! previous values.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert_after(const_iterator prev_pos, detail::moved_object<value_type> x)
- { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
- #else
- iterator insert_after(const_iterator prev_pos, value_type && x)
- { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(detail::move_impl(x)))); }
- #endif
-
- //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts n copies of x after prev_pos.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references of
- //! previous values.
- void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
- { this->priv_create_and_insert_nodes(prev_pos, n, x); }
-
- //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts the range pointed by [first, last)
- //! after the p prev_pos.
- //!
- //! <b>Throws</b>: If memory allocation throws, T's constructor from a
- //! dereferenced InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to the number of elements inserted.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references of
- //! previous values.
- template <class InIter>
- void insert_after(const_iterator prev_pos, InIter first, InIter last)
- {
- const bool aux_boolean = detail::is_convertible<InIter, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
- }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of x before p.
- //!
- //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the elements before p.
- iterator insert(const_iterator p, const value_type& x)
- { return this->insert_after(previous(p), x); }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Linear to the elements before p.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator p, detail::moved_object<value_type> x)
- { return this->insert_after(previous(p), x); }
- #else
- iterator insert(const_iterator p, value_type && x)
- { return this->insert_after(previous(p), detail::move_impl(x)); }
- #endif
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts n copies of x before p.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
- void insert(const_iterator p, size_type n, const value_type& x)
- { return this->insert_after(previous(p), n, x); }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
- //!
- //! <b>Throws</b>: If memory allocation throws, T's constructor from a
- //! dereferenced InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to std::distance [first, last) plus
- //! linear to the elements before p.
- template <class InIter>
- void insert(const_iterator p, InIter first, InIter last)
- { return this->insert_after(previous(p), first, last); }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the front of the list
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- template <class... Args>
- void emplace_front(Args&&... args)
- { this->emplace_after(this->cbefore_begin(), detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... before p
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the elements before p
- template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
- { return this->emplace_after(this->previous(p), detail::forward_impl<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... after prev
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- iterator emplace_after(const_iterator prev, Args&&... args)
- {
- typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
- new ((void*)detail::get_pointer(d.get())) Node(detail::forward_impl<Args>(args)...);
- NodePtr node = d.get();
- d.release();
- return iterator(this->icont().insert_after(prev.get(), *node));
- }
-
- #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //0 args
- void emplace_front()
- { this->emplace_after(this->cbefore_begin()); }
-
- iterator emplace(const_iterator p)
- { return this->emplace_after(this->previous(p)); }
-
- iterator emplace_after(const_iterator prev)
- {
- typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
- new ((void*)detail::get_pointer(d.get())) Node();
- NodePtr node = d.get();
- d.release();
- return iterator(this->icont().insert_after(prev.get(), *node));
- }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- this->emplace \
- (this->cbegin(), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace \
- (const_iterator p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_after \
- (this->previous(p), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace_after \
- (const_iterator prev, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
- new ((void*)detail::get_pointer(d.get())) \
- Node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- NodePtr node = d.get(); \
- d.release(); \
- return iterator(this->icont().insert_after(prev.get(), *node)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Erases the element after the element pointed by prev_pos
- //! of the list.
- //!
- //! <b>Returns</b>: the first element remaining beyond the removed elements,
- //! or end() if no such element exists.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
- iterator erase_after(const_iterator prev_pos)
- {
- return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
- }
-
- //! <b>Effects</b>: Erases the range (before_first, last) from
- //! the list.
- //!
- //! <b>Returns</b>: the first element remaining beyond the removed elements,
- //! or end() if no such element exists.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of erased elements.
- //!
- //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
- iterator erase_after(const_iterator before_first, const_iterator last)
- {
- return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
- }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Erases the element at p p.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements before p.
- iterator erase(const_iterator p)
- { return iterator(this->erase_after(previous(p))); }
-
- //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
- //!
- //! <b>Effects</b>: Erases the elements pointed by [first, last).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the distance between first and last plus
- //! linear to the elements before first.
- iterator erase(const_iterator first, const_iterator last)
- { return iterator(this->erase_after(previous(first), last)); }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size, const T& x)
- {
- typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
- while (++(cur_next = cur) != end_n && new_size > 0){
- --new_size;
- cur = cur_next;
- }
- if (cur_next != end_n)
- this->erase_after(const_iterator(cur), const_iterator(end_n));
- else
- this->insert_after(const_iterator(cur), new_size, x);
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size)
- {
- typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
- size_type len = this->size();
- size_type left = new_size;
-
- while (++(cur_next = cur) != end_n && left > 0){
- --left;
- cur = cur_next;
- }
- if (cur_next != end_n){
- this->erase_after(const_iterator(cur), const_iterator(end_n));
- }
- else{
- this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
- }
- }
-
- //! <b>Effects</b>: Erases all the elements of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the list.
- void clear()
- { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
- //!
- //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
- //! the element pointed by p. No destructors or copy constructors are called.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Linear to the elements in x.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
- //! this list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice_after(const_iterator prev_pos, detail::moved_object<slist> x)
- { this->splice_after(prev_pos, x.get()); }
- void splice_after(const_iterator prev_pos, slist& x)
- #else
- void splice_after(const_iterator prev_pos, slist&& x)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after(prev_pos.get(), x.icont());
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: prev_pos must be a valid iterator of this.
- //! i must point to an element contained in list x.
- //!
- //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
- //! after the element pointed by prev_pos.
- //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice_after(const_iterator prev_pos, detail::moved_object<slist> x, const_iterator prev)
- { this->splice_after(prev_pos, x.get(), prev); }
- void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
- #else
- void splice_after(const_iterator prev_pos, slist&& x, const_iterator prev)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: prev_pos must be a valid iterator of this.
- //! before_first and before_last must be valid iterators of x.
- //! prev_pos must not be contained in [before_first, before_last) range.
- //!
- //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
- //! from list x to this list, after the element pointed by prev_pos.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Linear to the number of transferred elements.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice_after(const_iterator prev_pos, detail::moved_object<slist> x,
- const_iterator before_first, const_iterator before_last)
- { this->splice_after(prev_pos, x.get(), before_first, before_last); }
- void splice_after(const_iterator prev_pos, slist& x,
- const_iterator before_first, const_iterator before_last)
- #else
- void splice_after(const_iterator prev_pos, slist&& x,
- const_iterator before_first, const_iterator before_last)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after
- (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: prev_pos must be a valid iterator of this.
- //! before_first and before_last must be valid iterators of x.
- //! prev_pos must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last)
- //!
- //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
- //! from list x to this list, after the element pointed by prev_pos.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice_after(const_iterator prev_pos, detail::moved_object<slist> x,
- const_iterator before_first, const_iterator before_last,
- size_type n)
- { this->splice_after(prev_pos, x.get(), before_first, before_last, n); }
- void splice_after(const_iterator prev_pos, slist& x,
- const_iterator before_first, const_iterator before_last,
- size_type n)
- #else
- void splice_after(const_iterator prev_pos, slist&& x,
- const_iterator before_first, const_iterator before_last,
- size_type n)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after
- (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
- }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
- //!
- //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
- //! the element pointed by p. No destructors or copy constructors are called.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
- //! this list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(const_iterator p, detail::moved_object<ThisType> x)
- { this->splice(p, x.get()); }
- void splice(const_iterator p, ThisType& x)
- #else
- void splice(const_iterator p, ThisType&& x)
- #endif
- { this->splice_after(this->previous(p), x); }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. i must point to an element contained in list x.
- //!
- //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
- //! If p == i or p == ++i, this function is a null operation.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator i)
- { this->splice(p, x.get(), i); }
- void splice(const_iterator p, slist& x, const_iterator i)
- #else
- void splice(const_iterator p, slist&& x, const_iterator i)
- #endif
- { this->splice_after(previous(p), x, i); }
-
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. first and last must point to elements contained in list x.
- //!
- //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
- //!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
- //!
- //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
- //! and in distance(first, last).
- //!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
- //! list. Iterators of this list and all the references are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator first, const_iterator last)
- { this->splice(p, x.get(), first, last); }
- void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
- #else
- void splice(const_iterator p, slist&& x, const_iterator first, const_iterator last)
- #endif
- { this->splice_after(previous(p), x, previous(first), previous(last)); }
-
- //! <b>Effects</b>: Reverses the order of elements in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time.
- //!
- //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
- { this->icont().reverse(); }
-
- //! <b>Effects</b>: Removes all the elements that compare equal to value.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- void remove(const T& value)
- { remove_if(equal_to_value(value)); }
-
- //! <b>Effects</b>: Removes all the elements for which a specified
- //! predicate is satisfied.
- //!
- //! <b>Throws</b>: If pred throws.
- //!
- //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- template <class Pred>
- void remove_if(Pred pred)
- {
- typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
- }
-
- //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
- //! elements that are equal from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- void unique()
- { this->unique(value_equal()); }
-
- //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
- //! elements that satisfy some binary predicate from the list.
- //!
- //! <b>Throws</b>: If pred throws.
- //!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
- //!
- //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
- //! and iterators to elements that are not removed remain valid.
- template <class Pred>
- void unique(Pred pred)
- {
- typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
- }
-
- //! <b>Requires</b>: The lists x and *this must be distinct.
- //!
- //! <b>Effects</b>: This function removes all of x's elements and inserts them
- //! in order into *this according to std::less<value_type>. The merge is stable;
- //! that is, if an element from *this is equivalent to one from x, then the element
- //! from *this will precede the one from x.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time: it performs at most
- //! size() + x.size() - 1 comparisons.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void merge(detail::moved_object<slist<T, A> > x)
- { this->merge(x.get()); }
- void merge(slist<T, A>& x)
- #else
- void merge(slist<T, A>&& x)
- #endif
- { this->merge(x, value_less()); }
-
- //! <b>Requires</b>: p must be a comparison function that induces a strict weak
- //! ordering and both *this and x must be sorted according to that ordering
- //! The lists x and *this must be distinct.
- //!
- //! <b>Effects</b>: This function removes all of x's elements and inserts them
- //! in order into *this. The merge is stable; that is, if an element from *this is
- //! equivalent to one from x, then the element from *this will precede the one from x.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time: it performs at most
- //! size() + x.size() - 1 comparisons.
- //!
- //! <b>Note</b>: Iterators and references to *this are not invalidated.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- template <class StrictWeakOrdering>
- void merge(detail::moved_object<slist<T, A> > x, StrictWeakOrdering comp)
- { this->merge(x.get(), comp); }
- template <class StrictWeakOrdering>
- void merge(slist<T, A>& x, StrictWeakOrdering comp)
- #else
- template <class StrictWeakOrdering>
- void merge(slist<T, A>&& x, StrictWeakOrdering comp)
- #endif
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
- else{
- throw std::runtime_error("list::merge called with unequal allocators");
- }
- }
-
- //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
- //! The sort is stable, that is, the relative order of equivalent elements is preserved.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Notes</b>: Iterators and references are not invalidated.
- //!
- //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
- //! is the list's size.
- void sort()
- { this->sort(value_less()); }
-
- //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
- //! The sort is stable, that is, the relative order of equivalent elements is preserved.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Notes</b>: Iterators and references are not invalidated.
- //!
- //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
- //! is the list's size.
- template <class StrictWeakOrdering>
- void sort(StrictWeakOrdering comp)
- {
- // nothing if the slist has length 0 or 1.
- if (this->size() < 2)
- return;
- this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
-
- /// @cond
- private:
-
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, InpIterator beg, InpIterator end)
- {
- typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat());
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
- {
- for (; beg != end; ++beg){
- this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
- ++prev;
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
- }
-
- class insertion_functor;
- friend class insertion_functor;
-
- class insertion_functor
- {
- Icont &icont_;
- typename Icont::const_iterator prev_;
-
- public:
- insertion_functor(Icont &icont, typename Icont::const_iterator prev)
- : icont_(icont), prev_(prev)
- {}
-
- void operator()(Node &n)
- { prev_ = this->icont_.insert_after(prev_, n); }
- };
-
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
- {
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
- }
-
- //Default constructed version
- void priv_create_and_insert_nodes(const_iterator prev, size_type n)
- {
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator());
- }
-
- //Copy constructed version
- void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator());
- }
-
- //Dispatch to detect iterator range or integer overloads
- template <class InputIter>
- void priv_insert_dispatch(const_iterator prev,
- InputIter first, InputIter last,
- detail::false_)
- { this->priv_create_and_insert_nodes(prev, first, last); }
-
- template<class Integer>
- void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, detail::true_)
- { this->priv_create_and_insert_nodes(prev, n, x); }
-
- void priv_fill_assign(size_type n, const T& val)
- {
- iterator end_n(this->end());
- iterator prev(this->before_begin());
- iterator node(this->begin());
- for ( ; node != end_n && n > 0 ; --n){
- *node = val;
- prev = node;
- ++node;
- }
- if (n > 0)
- this->priv_create_and_insert_nodes(prev, n, val);
- else
- this->erase_after(prev, end_n);
- }
-
- template <class Int>
- void priv_assign_dispatch(Int n, Int val, detail::true_)
- { this->priv_fill_assign((size_type) n, (T)val); }
-
- template <class InpIt>
- void priv_assign_dispatch(InpIt first, InpIt last, detail::false_)
- {
- iterator end_n(this->end());
- iterator prev(this->before_begin());
- iterator node(this->begin());
- while (node != end_n && first != last){
- *node = *first;
- prev = node;
- ++node;
- ++first;
- }
- if (first != last)
- this->priv_create_and_insert_nodes(prev, first, last);
- else
- this->erase_after(prev, end_n);
- }
-
- template <class Int>
- void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, detail::true_)
- { this->priv_create_and_insert_nodes(prev_pos, n, x); }
-
- template <class InIter>
- void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, detail::false_)
- { this->priv_create_and_insert_nodes(prev_pos, first, last); }
-
- //Functors for member algorithm defaults
- struct value_less
- {
- bool operator()(const value_type &a, const value_type &b) const
- { return a < b; }
- };
-
- struct value_equal
- {
- bool operator()(const value_type &a, const value_type &b) const
- { return a == b; }
- };
-
- struct value_equal_to_this
- {
- explicit value_equal_to_this(const value_type &ref)
- : m_ref(ref){}
-
- bool operator()(const value_type &val) const
- { return m_ref == val; }
-
- const value_type &m_ref;
- };
- /// @endcond
-};
-
-template <class T, class A>
-inline bool
-operator==(const slist<T,A>& x, const slist<T,A>& y)
-{
- if(x.size() != y.size()){
- return false;
- }
- typedef typename slist<T,A>::const_iterator const_iterator;
- const_iterator end1 = x.end();
-
- const_iterator i1 = x.begin();
- const_iterator i2 = y.begin();
- while (i1 != end1 && *i1 == *i2){
- ++i1;
- ++i2;
- }
- return i1 == end1;
-}
-
-template <class T, class A>
-inline bool
-operator<(const slist<T,A>& sL1, const slist<T,A>& sL2)
-{
- return std::lexicographical_compare
- (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
-}
-
-template <class T, class A>
-inline bool
-operator!=(const slist<T,A>& sL1, const slist<T,A>& sL2)
- { return !(sL1 == sL2); }
-
-template <class T, class A>
-inline bool
-operator>(const slist<T,A>& sL1, const slist<T,A>& sL2)
- { return sL2 < sL1; }
-
-template <class T, class A>
-inline bool
-operator<=(const slist<T,A>& sL1, const slist<T,A>& sL2)
- { return !(sL2 < sL1); }
-
-template <class T, class A>
-inline bool
-operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2)
- { return !(sL1 < sL2); }
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class A>
-inline void swap(slist<T,A>& x, slist<T,A>& y)
- { x.swap(y); }
-
-template <class T, class A>
-inline void swap(detail::moved_object<slist<T,A> > x, slist<T,A>& y)
- { x.get().swap(y); }
-
-template <class T, class A>
-inline void swap(slist<T,A>& x, detail::moved_object<slist<T,A> > y)
- { x.swap(y.get()); }
-#else
-template <class T, class A>
-inline void swap(slist<T,A>&&x, slist<T,A>&&y)
- { x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class A>
-struct is_movable<slist<T, A> >
-{
- enum { value = true };
-};
-
-//!This class is movable
-template <class A, class VoidPointer>
-struct is_movable<detail::slist_node<A, VoidPointer> >
-{
- enum { value = true };
-};
-
-//!This class is movable
-/*
-template <class A>
-struct is_movable<detail::slist_alloc<A> >
-{
- enum { value = true };
-};
-*/
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class A>
-struct has_trivial_destructor_after_move<slist<T, A> >
-{
- enum { value = has_trivial_destructor<A>::value };
-};
-/// @endcond
-
-}} //namespace boost{ namespace interprocess{
-
-// Specialization of insert_iterator so that insertions will be constant
-// time rather than linear time.
-
-///@cond
-
-//Ummm, I don't like to define things in namespace std, but
-//there is no other way
-namespace std {
-
-template <class T, class A>
-class insert_iterator<boost::interprocess::slist<T, A> >
-{
- protected:
- typedef boost::interprocess::slist<T, A> Container;
- Container* container;
- typename Container::iterator iter;
- public:
- typedef Container container_type;
- typedef output_iterator_tag iterator_category;
- typedef void value_type;
- typedef void difference_type;
- typedef void pointer;
- typedef void reference;
-
- insert_iterator(Container& x,
- typename Container::iterator i,
- bool is_previous = false)
- : container(&x), iter(is_previous ? i : x.previous(i)){ }
+#include <boost/interprocess/containers/container/slist.hpp>
- insert_iterator<Container>&
- operator=(const typename Container::value_type& value)
- {
- iter = container->insert_after(iter, value);
- return *this;
- }
- insert_iterator<Container>& operator*(){ return *this; }
- insert_iterator<Container>& operator++(){ return *this; }
- insert_iterator<Container>& operator++(int){ return *this; }
-};
+namespace boost {
+namespace interprocess {
-} //namespace std;
+using boost::interprocess_container::slist;
-///@endcond
+} //namespace interprocess {
+} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_SLIST_HPP */
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_SLIST_HPP
Added: trunk/boost/interprocess/containers/stable_vector.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/stable_vector.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_CONTAINERS_STABLE_VECTOR_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_STABLE_VECTOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/stable_vector.hpp>
+
+namespace boost {
+ namespace interprocess {
+
+ using boost::interprocess_container::stable_vector;
+
+ } //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_STABLE_VECTOR_HPP
Modified: trunk/boost/interprocess/containers/string.hpp
==============================================================================
--- trunk/boost/interprocess/containers/string.hpp (original)
+++ trunk/boost/interprocess/containers/string.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,2491 +1,32 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2008
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 1994
-// Hewlett-Packard Company
-//
-// Permission to use, copy, modify, distribute and sell this software
-// and its documentation for any purpose is hereby granted without fee,
-// provided that the above copyright notice appear in all copies and
-// that both that copyright notice and this permission notice appear
-// in supporting documentation. Hewlett-Packard Company makes no
-// representations about the suitability of this software for any
-// purpose. It is provided "as is" without express or implied warranty.
-#ifndef BOOST_INTERPROCESS_STRING_HPP
-#define BOOST_INTERPROCESS_STRING_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_STRING_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_STRING_HPP
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
-#include <boost/interprocess/detail/min_max.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/static_assert.hpp>
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
-#include <functional>
-#include <string>
-#include <stdexcept>
-#include <utility>
-#include <iterator>
-#include <memory>
-#include <algorithm>
-#include <iosfwd>
-#include <istream>
-#include <ostream>
-#include <ios>
-#include <locale>
-#include <cstddef>
-#include <climits>
-#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/string.hpp>
namespace boost {
namespace interprocess {
-namespace detail {
-
-/// @cond
-// ------------------------------------------------------------
-// Class basic_string_base.
-
-// basic_string_base is a helper class that makes it it easier to write
-// an exception-safe version of basic_string. The constructor allocates,
-// but does not initialize, a block of memory. The destructor
-// deallocates, but does not destroy elements within, a block of
-// memory. The destructor assumes that the memory either is the internal buffer,
-// or else points to a block of memory that was allocated using _String_base's
-// allocator and whose size is this->m_storage.
-template <class A>
-class basic_string_base
-{
- basic_string_base();
- public:
- typedef A allocator_type;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
- typedef typename A::pointer pointer;
- typedef typename A::value_type value_type;
- typedef typename A::size_type size_type;
-
- basic_string_base(const allocator_type& a)
- : members_(a)
- { init(); }
-
- basic_string_base(const allocator_type& a, std::size_t n)
- : members_(a)
- {
- this->init();
- this->allocate_initial_block(n);
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE)
- basic_string_base(detail::moved_object<basic_string_base<A> > b)
- : members_(b.get().members_)
- {
- init();
- this->swap(b.get());
- }
- #else
- basic_string_base(basic_string_base<A> && b)
- : members_(b.members_)
- {
- init();
- this->swap(b);
- }
- #endif
-
- ~basic_string_base()
- {
- this->deallocate_block();
- if(!this->is_short()){
- static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
- }
- }
-
- private:
-
- //This is the structure controlling a long string
- struct long_t
- {
- size_type is_short : 1;
- size_type length : (sizeof(size_type)*CHAR_BIT - 1);
- size_type storage;
- pointer start;
-
- long_t()
- {}
-
- long_t(const long_t &other)
- {
- this->is_short = other.is_short;
- length = other.length;
- storage = other.storage;
- start = other.start;
- }
-
- long_t &operator =(const long_t &other)
- {
- this->is_short = other.is_short;
- length = other.length;
- storage = other.storage;
- start = other.start;
- return *this;
- }
- };
-
- //This basic type should have the same alignment as long_t
-//iG typedef typename type_with_alignment<detail::alignment_of<long_t>::value>::type
-// long_alignment_type;
- typedef void *long_alignment_type;
- BOOST_STATIC_ASSERT((detail::alignment_of<long_alignment_type>::value %
- detail::alignment_of<long_t>::value) == 0);
-
-
- //This type is the first part of the structure controlling a short string
- //The "data" member stores
- struct short_header
- {
- unsigned char is_short : 1;
- unsigned char length : (CHAR_BIT - 1);
- };
-
- //This type has the same alignment and size as long_t but it's POD
- //so, unlike long_t, it can be placed in a union
- struct long_raw_t
- {
- long_alignment_type a;
- unsigned char b[sizeof(long_t) - sizeof(long_alignment_type)];
- };
-
- protected:
- static const size_type MinInternalBufferChars = 8;
- static const size_type AlignmentOfValueType =
- alignment_of<value_type>::value;
- static const size_type ShortDataOffset =
- detail::ct_rounded_size<sizeof(short_header), AlignmentOfValueType>::value;
- static const size_type ZeroCostInternalBufferChars =
- (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
- static const size_type UnalignedFinalInternalBufferChars =
- (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
- ZeroCostInternalBufferChars : MinInternalBufferChars;
-
- struct short_t
- {
- short_header h;
- value_type data[UnalignedFinalInternalBufferChars];
- };
-
- union repr_t
- {
- long_raw_t r;
- short_t s;
-
- short_t &short_repr() const
- { return *const_cast<short_t *>(&s); }
-
- long_t &long_repr() const
- { return *static_cast<long_t*>(const_cast<void*>(static_cast<const void*>(&r))); }
- };
-
- struct members_holder
- : public A
- {
- members_holder(const A &a)
- : A(a)
- {}
-
- repr_t m_repr;
- } members_;
-
- const A &alloc() const
- { return members_; }
-
- A &alloc()
- { return members_; }
-
- static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
-
- private:
-
- static const size_type MinAllocation = InternalBufferChars*2;
-
- protected:
- bool is_short() const
- { return static_cast<bool>(this->members_.m_repr.s.h.is_short != 0); }
-
- void is_short(bool yes)
- {
- if(yes && !this->is_short()){
- static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
- }
- else{
- new(static_cast<void*>(&this->members_.m_repr.r))long_t();
- }
- this->members_.m_repr.s.h.is_short = yes;
- }
-
- private:
- void init()
- {
- this->members_.m_repr.s.h.is_short = 1;
- this->members_.m_repr.s.h.length = 0;
- }
-
- protected:
-
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
- typedef detail::integral_constant<unsigned,
- boost::interprocess::detail::version<A>::value> alloc_version;
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size, pointer reuse = 0)
- {
- if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
- reuse = pointer(0);
- command &= ~(expand_fwd | expand_bwd);
- }
- return this->allocation_command
- (command, limit_size, preferred_size, received_size, reuse, alloc_version());
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v1)
- {
- (void)limit_size;
- (void)reuse;
- if(!(command & allocate_new))
- return std::pair<pointer, bool>(pointer(0), 0);
- received_size = preferred_size;
- return std::make_pair(this->alloc().allocate(received_size), false);
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- pointer reuse,
- allocator_v2)
- {
- return this->alloc().allocation_command(command, limit_size, preferred_size,
- received_size, reuse);
- }
-
- size_type next_capacity(size_type additional_objects) const
- { return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects); }
-
- void deallocate(pointer p, std::size_t n)
- {
- if (p && (n > InternalBufferChars))
- this->alloc().deallocate(p, n);
- }
-
- void construct(pointer p, const value_type &value = value_type())
- { new((void*)detail::get_pointer(p)) value_type(value); }
-
- void destroy(pointer p, size_type n)
- {
- for(; n--; ++p)
- detail::get_pointer(p)->~value_type();
- }
-
- void destroy(pointer p)
- { detail::get_pointer(p)->~value_type(); }
-
- void allocate_initial_block(std::size_t n)
- {
- if (n <= this->max_size()) {
- if(n > InternalBufferChars){
- size_type new_cap = this->next_capacity(n);
- pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
- this->is_short(false);
- this->priv_addr(p);
- this->priv_size(0);
- this->priv_storage(new_cap);
- }
- }
- else
- throw_length_error();
- }
-
- void deallocate_block()
- { this->deallocate(this->priv_addr(), this->priv_storage()); }
-
- std::size_t max_size() const
- { return this->alloc().max_size() - 1; }
-
- // Helper functions for exception handling.
- void throw_length_error() const
- { throw(std::length_error("basic_string")); }
-
- void throw_out_of_range() const
- { throw(std::out_of_range("basic_string")); }
-
- protected:
- size_type priv_capacity() const
- { return this->priv_storage() - 1; }
-
- pointer priv_addr() const
- { return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start; }
-
- void priv_addr(pointer addr)
- { this->members_.m_repr.long_repr().start = addr; }
-
- size_type priv_storage() const
- { return this->is_short() ? InternalBufferChars : this->members_.m_repr.long_repr().storage; }
-
- void priv_storage(size_type storage)
- {
- if(!this->is_short())
- this->members_.m_repr.long_repr().storage = storage;
- }
-
- size_type priv_size() const
- { return this->is_short() ? this->members_.m_repr.short_repr().h.length : this->members_.m_repr.long_repr().length; }
-
- void priv_size(size_type sz)
- {
- if(this->is_short())
- this->members_.m_repr.s.h.length = (unsigned char)sz;
- else
- this->members_.m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
- }
-
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_string_base> x)
- { this->swap(x.get()); }
- void swap(basic_string_base& other)
- #else
- void swap(basic_string_base &&other)
- #endif
- {
- if(this->is_short()){
- if(other.is_short()){
- std::swap(this->members_.m_repr, other.members_.m_repr);
- }
- else{
- repr_t copied(this->members_.m_repr);
- this->members_.m_repr.long_repr() = other.members_.m_repr.long_repr();
- other.members_.m_repr = copied;
- }
- }
- else{
- if(other.is_short()){
- repr_t copied(other.members_.m_repr);
- other.members_.m_repr.long_repr() = this->members_.m_repr.long_repr();
- this->members_.m_repr = copied;
- }
- else{
- std::swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
- }
- }
-
- allocator_type & this_al = this->alloc(), &other_al = other.alloc();
- if(this_al != other_al){
- detail::do_swap(this_al, other_al);
- }
- }
-};
-/// @endcond
-
-} //namespace detail {
-
-
-//! The basic_string class represents a Sequence of characters. It contains all the
-//! usual operations of a Sequence, and, additionally, it contains standard string
-//! operations such as search and concatenation.
-//!
-//! The basic_string class is parameterized by character type, and by that type's
-//! Character Traits.
-//!
-//! This class has performance characteristics very much like vector<>, meaning,
-//! for example, that it does not perform reference-count or copy-on-write, and that
-//! concatenation of two strings is an O(N) operation.
-//!
-//! Some of basic_string's member functions use an unusual method of specifying positions
-//! and ranges. In addition to the conventional method using iterators, many of
-//! basic_string's member functions use a single value pos of type size_type to represent a
-//! position (in which case the position is begin() + pos, and many of basic_string's
-//! member functions use two values, pos and n, to represent a range. In that case pos is
-//! the beginning of the range and n is its size. That is, the range is
-//! [begin() + pos, begin() + pos + n).
-//!
-//! Note that the C++ standard does not specify the complexity of basic_string operations.
-//! In this implementation, basic_string has performance characteristics very similar to
-//! those of vector: access to a single character is O(1), while copy and concatenation
-//! are O(N).
-//!
-//! In this implementation, begin(),
-//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
-//! In this implementation, iterators are only invalidated by member functions that
-//! explicitly change the string's contents.
-template <class CharT, class Traits, class A>
-class basic_string
- : private detail::basic_string_base<A>
-{
- /// @cond
- private:
- typedef detail::basic_string_base<A> base_t;
- static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
-
- protected:
- // A helper class to use a char_traits as a function object.
-
- template <class Tr>
- struct Eq_traits
- : public std::binary_function<typename Tr::char_type,
- typename Tr::char_type,
- bool>
- {
- bool operator()(const typename Tr::char_type& x,
- const typename Tr::char_type& y) const
- { return Tr::eq(x, y); }
- };
-
- template <class Tr>
- struct Not_within_traits
- : public std::unary_function<typename Tr::char_type, bool>
- {
- typedef const typename Tr::char_type* Pointer;
- const Pointer m_first;
- const Pointer m_last;
-
- Not_within_traits(Pointer f, Pointer l)
- : m_first(f), m_last(l) {}
-
- bool operator()(const typename Tr::char_type& x) const
- {
- return std::find_if(m_first, m_last,
- std::bind1st(Eq_traits<Tr>(), x)) == m_last;
- }
- };
- /// @endcond
-
- public:
- //! The allocator type
- typedef A allocator_type;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
- //! The type of object, CharT, stored in the string
- typedef CharT value_type;
- //! The second template parameter Traits
- typedef Traits traits_type;
- //! Pointer to CharT
- typedef typename A::pointer pointer;
- //! Const pointer to CharT
- typedef typename A::const_pointer const_pointer;
- //! Reference to CharT
- typedef typename A::reference reference;
- //! Const reference to CharT
- typedef typename A::const_reference const_reference;
- //! An unsigned integral type
- typedef typename A::size_type size_type;
- //! A signed integral type
- typedef typename A::difference_type difference_type;
- //! Iterator used to iterate through a string. It's a Random Access Iterator
- typedef pointer iterator;
- //! Const iterator used to iterate through a string. It's a Random Access Iterator
- typedef const_pointer const_iterator;
- //! Iterator used to iterate backwards through a string
- typedef std::reverse_iterator<iterator> reverse_iterator;
- //! Const iterator used to iterate backwards through a string
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- //! The largest possible value of type size_type. That is, size_type(-1).
- static const size_type npos;
-
- /// @cond
- private:
- typedef constant_iterator<CharT, difference_type> cvalue_iterator;
- /// @endcond
-
- public: // Constructor, destructor, assignment.
- /// @cond
- struct reserve_t {};
- /// @endcond
-
- basic_string(reserve_t, std::size_t n,
- const allocator_type& a = allocator_type())
- : base_t(a, n + 1)
- { this->priv_terminate_string(); }
-
- //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- explicit basic_string(const allocator_type& a = allocator_type())
- : base_t(a, InternalBufferChars)
- { this->priv_terminate_string(); }
-
- //! <b>Effects</b>: Copy constructs a basic_string.
- //!
- //! <b>Postcondition</b>: x == *this.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
- basic_string(const basic_string& s)
- : base_t(s.alloc())
- { this->priv_range_initialize(s.begin(), s.end()); }
-
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_string(detail::moved_object<basic_string> s)
- : base_t(detail::move_impl((base_t&)s.get()))
- {}
- #else
- basic_string(basic_string && s)
- : base_t(detail::move_impl((base_t&)s))
- {}
- #endif
-
- //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
- //! and is initialized by a specific number of characters of the s string.
- basic_string(const basic_string& s, size_type pos, size_type n = npos,
- const allocator_type& a = allocator_type())
- : base_t(a)
- {
- if (pos > s.size())
- this->throw_out_of_range();
- else
- this->priv_range_initialize
- (s.begin() + pos, s.begin() + pos + min_value(n, s.size() - pos));
- }
-
- //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
- //! and is initialized by a specific number of characters of the s c-string.
- basic_string(const CharT* s, size_type n,
- const allocator_type& a = allocator_type())
- : base_t(a)
- { this->priv_range_initialize(s, s + n); }
-
- //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
- //! and is initialized by the null-terminated s c-string.
- basic_string(const CharT* s,
- const allocator_type& a = allocator_type())
- : base_t(a)
- { this->priv_range_initialize(s, s + Traits::length(s)); }
-
- //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
- //! and is initialized by n copies of c.
- basic_string(size_type n, CharT c,
- const allocator_type& a = allocator_type())
- : base_t(a)
- {
- this->priv_range_initialize(cvalue_iterator(c, n),
- cvalue_iterator());
- }
-
- //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
- //! and a range of iterators.
- template <class InputIterator>
- basic_string(InputIterator f, InputIterator l,
- const allocator_type& a = allocator_type())
- : base_t(a)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InputIterator, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_initialize_dispatch(f, l, Result());
- }
-
- //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- ~basic_string()
- {}
-
- //! <b>Effects</b>: Copy constructs a string.
- //!
- //! <b>Postcondition</b>: x == *this.
- //!
- //! <b>Complexity</b>: Linear to the elements x contains.
- basic_string& operator=(const basic_string& s)
- {
- if (&s != this)
- this->assign(s.begin(), s.end());
- return *this;
- }
-
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_string& operator=(detail::moved_object<basic_string> ms)
- {
- basic_string &s = ms.get();
- if (&s != this){
- this->swap(s);
- }
- return *this;
- }
- #else
- basic_string& operator=(basic_string && ms)
- {
- basic_string &s = ms;
- if (&s != this){
- this->swap(s);
- }
- return *this;
- }
- #endif
-
- //! <b>Effects</b>: Assignment from a null-terminated c-string.
- basic_string& operator=(const CharT* s)
- { return this->assign(s, s + Traits::length(s)); }
-
- //! <b>Effects</b>: Assignment from character.
- basic_string& operator=(CharT c)
- { return this->assign(static_cast<size_type>(1), c); }
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return this->priv_addr(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return this->priv_addr(); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return this->priv_addr() + this->priv_size(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return this->priv_addr() + this->priv_size(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return reverse_iterator(this->priv_addr() + this->priv_size()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
- { return const_reverse_iterator(this->priv_addr() + this->priv_size()); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return reverse_iterator(this->priv_addr()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return const_reverse_iterator(this->priv_addr()); }
-
- //! <b>Effects</b>: Returns a copy of the internal allocator.
- //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return this->alloc(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return this->priv_size(); }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type length() const
- { return this->size(); }
-
- //! <b>Effects</b>: Returns the largest possible size of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return base_t::max_size(); }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type n, CharT c)
- {
- if (n <= size())
- this->erase(this->begin() + n, this->end());
- else
- this->append(n - this->size(), c);
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type n)
- { resize(n, this->priv_null()); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
- //!
- //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
- void reserve(size_type res_arg)
- {
- if (res_arg > this->max_size())
- this->throw_length_error();
-
- if (this->capacity() < res_arg){
- size_type n = max_value(res_arg, this->size()) + 1;
- size_type new_cap = this->next_capacity(n);
- pointer new_start = this->allocation_command
- (allocate_new, n, new_cap, new_cap).first;
- size_type new_length = 0;
-
- new_length += priv_uninitialized_copy
- (this->priv_addr(), this->priv_addr() + this->priv_size(), new_start);
- this->priv_construct_null(new_start + new_length);
- this->deallocate_block();
- this->is_short(false);
- this->priv_addr(new_start);
- this->priv_size(new_length);
- this->priv_storage(new_cap);
- }
- }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return this->priv_capacity(); }
-
- //! <b>Effects</b>: Erases all the elements of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the vector.
- void clear()
- {
- if (!empty()) {
- Traits::assign(*this->priv_addr(), this->priv_null());
- this->priv_size(0);
- }
- }
-
- //! <b>Effects</b>: Returns true if the vector contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->priv_size(); }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
- { return *(this->priv_addr() + n); }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a const reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const
- { return *(this->priv_addr() + n); }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: std::range_error if n >= size()
- //!
- //! <b>Complexity</b>: Constant.
- reference at(size_type n) {
- if (n >= size())
- this->throw_out_of_range();
- return *(this->priv_addr() + n);
- }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a const reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: std::range_error if n >= size()
- //!
- //! <b>Complexity</b>: Constant.
- const_reference at(size_type n) const {
- if (n >= size())
- this->throw_out_of_range();
- return *(this->priv_addr() + n);
- }
-
- //! <b>Effects</b>: Appends string s to *this.
- basic_string& operator+=(const basic_string& s)
- { return this->append(s); }
-
- //! <b>Effects</b>: Appends c-string s to *this.
- basic_string& operator+=(const CharT* s)
- { return this->append(s); }
-
- //! <b>Effects</b>: Appends character c to *this.
- basic_string& operator+=(CharT c)
- { this->push_back(c); return *this; }
-
- //! <b>Effects</b>: Appends string s to *this.
- basic_string& append(const basic_string& s)
- { return this->append(s.begin(), s.end()); }
-
- //! <b>Effects</b>: Appends the range [pos, pos + n) from string s to *this.
- basic_string& append(const basic_string& s, size_type pos, size_type n)
- {
- if (pos > s.size())
- this->throw_out_of_range();
- return this->append(s.begin() + pos,
- s.begin() + pos + min_value(n, s.size() - pos));
- }
-
- //! <b>Effects</b>: Appends the range [s, s + n) from c-string s to *this.
- basic_string& append(const CharT* s, size_type n)
- { return this->append(s, s + n); }
-
- //! <b>Effects</b>: Appends the c-string s to *this.
- basic_string& append(const CharT* s)
- { return this->append(s, s + Traits::length(s)); }
-
- //! <b>Effects</b>: Appends the n times the character c to *this.
- basic_string& append(size_type n, CharT c)
- { return this->append(cvalue_iterator(c, n), cvalue_iterator()); }
-
- //! <b>Effects</b>: Appends the range [first, last) *this.
- template <class InputIter>
- basic_string& append(InputIter first, InputIter last)
- { this->insert(this->end(), first, last); return *this; }
-
- //! <b>Effects</b>: Inserts a copy of c at the end of the vector.
- void push_back(CharT c)
- {
- if (this->priv_size() < this->capacity()){
- this->priv_construct_null(this->priv_addr() + (this->priv_size() + 1));
- Traits::assign(this->priv_addr()[this->priv_size()], c);
- this->priv_size(this->priv_size()+1);
- }
- else{
- //No enough memory, insert a new object at the end
- this->append((size_type)1, c);
- }
- }
-
- //! <b>Effects</b>: Removes the last element from the vector.
- void pop_back()
- {
- Traits::assign(this->priv_addr()[this->priv_size()-1], this->priv_null());
- this->priv_size(this->priv_size()-1);;
- }
-
- //! <b>Effects</b>: Assigns the value s to *this.
- basic_string& assign(const basic_string& s)
- { return this->operator=(s); }
-
- //! <b>Effects</b>: Moves the resources from ms *this.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_string& assign(detail::moved_object<basic_string> ms)
- { return this->operator=(ms);}
- #else
- basic_string& assign(basic_string && ms)
- { return this->operator=(ms);}
- #endif
-
- //! <b>Effects</b>: Assigns the range [pos, pos + n) from s to *this.
- basic_string& assign(const basic_string& s,
- size_type pos, size_type n) {
- if (pos > s.size())
- this->throw_out_of_range();
- return this->assign(s.begin() + pos,
- s.begin() + pos + min_value(n, s.size() - pos));
- }
-
- //! <b>Effects</b>: Assigns the range [s, s + n) from s to *this.
- basic_string& assign(const CharT* s, size_type n)
- { return this->assign(s, s + n); }
-
- //! <b>Effects</b>: Assigns the c-string s to *this.
- basic_string& assign(const CharT* s)
- { return this->assign(s, s + Traits::length(s)); }
-
- //! <b>Effects</b>: Assigns the character c n-times to *this.
- basic_string& assign(size_type n, CharT c)
- { return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
-
- //! <b>Effects</b>: Assigns the range [first, last) to *this.
- template <class InputIter>
- basic_string& assign(InputIter first, InputIter last)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InputIter, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- return this->priv_assign_dispatch(first, last, Result());
- }
-
- //! <b>Effects</b>: Assigns the range [f, l) to *this.
- basic_string& assign(const CharT* f, const CharT* l)
- {
- const std::ptrdiff_t n = l - f;
- if (static_cast<size_type>(n) <= size()) {
- Traits::copy(detail::get_pointer(this->priv_addr()), f, n);
- this->erase(this->priv_addr() + n, this->priv_addr() + this->priv_size());
- }
- else {
- Traits::copy(detail::get_pointer(this->priv_addr()), f, this->priv_size());
- this->append(f + this->priv_size(), l);
- }
- return *this;
- }
-
- //! <b>Effects</b>: Inserts the string s before pos.
- basic_string& insert(size_type pos, const basic_string& s)
- {
- if (pos > size())
- this->throw_out_of_range();
- if (this->size() > this->max_size() - s.size())
- this->throw_length_error();
- this->insert(this->priv_addr() + pos, s.begin(), s.end());
- return *this;
- }
-
- //! <b>Effects</b>: Inserts the range [pos, pos + n) from string s before pos.
- basic_string& insert(size_type pos, const basic_string& s,
- size_type beg, size_type n)
- {
- if (pos > this->size() || beg > s.size())
- this->throw_out_of_range();
- size_type len = min_value(n, s.size() - beg);
- if (this->size() > this->max_size() - len)
- this->throw_length_error();
- const CharT *beg_ptr = detail::get_pointer(s.begin()) + beg;
- const CharT *end_ptr = beg_ptr + len;
- this->insert(this->priv_addr() + pos, beg_ptr, end_ptr);
- return *this;
- }
-
- //! <b>Effects</b>: Inserts the range [s, s + n) before pos.
- basic_string& insert(size_type pos, const CharT* s, size_type n)
- {
- if (pos > this->size())
- this->throw_out_of_range();
- if (this->size() > this->max_size() - n)
- this->throw_length_error();
- this->insert(this->priv_addr() + pos, s, s + n);
- return *this;
- }
-
- //! <b>Effects</b>: Inserts the c-string s before pos.
- basic_string& insert(size_type pos, const CharT* s)
- {
- if (pos > size())
- this->throw_out_of_range();
- size_type len = Traits::length(s);
- if (this->size() > this->max_size() - len)
- this->throw_length_error();
- this->insert(this->priv_addr() + pos, s, s + len);
- return *this;
- }
-
- //! <b>Effects</b>: Inserts the character c n-times before pos.
- basic_string& insert(size_type pos, size_type n, CharT c)
- {
- if (pos > this->size())
- this->throw_out_of_range();
- if (this->size() > this->max_size() - n)
- this->throw_length_error();
- this->insert(this->priv_addr() + pos, n, c);
- return *this;
- }
-
- //! <b>Effects</b>: Inserts the character c before position.
- iterator insert(iterator position, CharT c)
- {
- size_type new_offset = position - this->priv_addr() + 1;
- this->insert(position, cvalue_iterator(c, 1),
- cvalue_iterator());
- return this->priv_addr() + new_offset;
- }
-
- //! <b>Effects</b>: Inserts the character c n-times before position.
- void insert(iterator position, std::size_t n, CharT c)
- {
- this->insert(position, cvalue_iterator(c, n),
- cvalue_iterator());
- }
-
- //! <b>Effects</b>: Inserts the range [first, last) before position.
- template <class InputIter>
- void insert(iterator p, InputIter first, InputIter last)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InputIter, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(p, first, last, Result());
- }
-
- //! <b>Effects</b>: Inserts the range [pos, pos + n).
- basic_string& erase(size_type pos = 0, size_type n = npos)
- {
- if (pos > size())
- this->throw_out_of_range();
- erase(this->priv_addr() + pos, this->priv_addr() + pos + min_value(n, size() - pos));
- return *this;
- }
-
- //! <b>Effects</b>: Erases the character pointed by position.
- iterator erase(iterator position)
- {
- // The move includes the terminating null.
- Traits::move(detail::get_pointer(position),
- detail::get_pointer(position + 1),
- this->priv_size() - (position - this->priv_addr()));
- this->priv_size(this->priv_size()-1);
- return position;
- }
-
- //! <b>Effects</b>: Erases the range [first, last).
- iterator erase(iterator first, iterator last)
- {
- if (first != last) { // The move includes the terminating null.
- size_type num_erased = last - first;
- Traits::move(detail::get_pointer(first),
- detail::get_pointer(last),
- (this->priv_size() + 1)-(last - this->priv_addr()));
- size_type new_length = this->priv_size() - num_erased;
- this->priv_size(new_length);
- }
- return first;
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with the string s.
- basic_string& replace(size_type pos, size_type n,
- const basic_string& s)
- {
- if (pos > size())
- this->throw_out_of_range();
- const size_type len = min_value(n, size() - pos);
- if (this->size() - len >= this->max_size() - s.size())
- this->throw_length_error();
- return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
- s.begin(), s.end());
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with a substring of s.
- basic_string& replace(size_type pos1, size_type n1,
- const basic_string& s,
- size_type pos2, size_type n2)
- {
- if (pos1 > size() || pos2 > s.size())
- this->throw_out_of_range();
- const size_type len1 = min_value(n1, size() - pos1);
- const size_type len2 = min_value(n2, s.size() - pos2);
- if (this->size() - len1 >= this->max_size() - len2)
- this->throw_length_error();
- return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len1,
- s.priv_addr() + pos2, s.priv_addr() + pos2 + len2);
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with the first n1 characters of s.
- basic_string& replace(size_type pos, size_type n1,
- const CharT* s, size_type n2)
- {
- if (pos > size())
- this->throw_out_of_range();
- const size_type len = min_value(n1, size() - pos);
- if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
- this->throw_length_error();
- return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
- s, s + n2);
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with a null-terminated character array.
- basic_string& replace(size_type pos, size_type n1,
- const CharT* s)
- {
- if (pos > size())
- this->throw_out_of_range();
- const size_type len = min_value(n1, size() - pos);
- const size_type n2 = Traits::length(s);
- if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
- this->throw_length_error();
- return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
- s, s + Traits::length(s));
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with n1 copies of c.
- basic_string& replace(size_type pos, size_type n1,
- size_type n2, CharT c)
- {
- if (pos > size())
- this->throw_out_of_range();
- const size_type len = min_value(n1, size() - pos);
- if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
- this->throw_length_error();
- return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len, n2, c);
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with the string s.
- basic_string& replace(iterator first, iterator last,
- const basic_string& s)
- { return this->replace(first, last, s.begin(), s.end()); }
-
- //! <b>Effects</b>: Replaces a substring of *this with the first n characters of s.
- basic_string& replace(iterator first, iterator last,
- const CharT* s, size_type n)
- { return this->replace(first, last, s, s + n); }
-
- //! <b>Effects</b>: Replaces a substring of *this with a null-terminated character array.
- basic_string& replace(iterator first, iterator last,
- const CharT* s)
- { return this->replace(first, last, s, s + Traits::length(s)); }
-
- //! <b>Effects</b>: Replaces a substring of *this with n copies of c.
- basic_string& replace(iterator first, iterator last,
- size_type n, CharT c)
- {
- const size_type len = static_cast<size_type>(last - first);
- if (len >= n) {
- Traits::assign(detail::get_pointer(first), n, c);
- erase(first + n, last);
- }
- else {
- Traits::assign(detail::get_pointer(first), len, c);
- insert(last, n - len, c);
- }
- return *this;
- }
-
- //! <b>Effects</b>: Replaces a substring of *this with the range [f, l)
- template <class InputIter>
- basic_string& replace(iterator first, iterator last,
- InputIter f, InputIter l)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InputIter, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- return this->priv_replace_dispatch(first, last, f, l, Result());
- }
-
- //! <b>Effects</b>: Copies a substring of *this to a buffer.
- size_type copy(CharT* s, size_type n, size_type pos = 0) const
- {
- if (pos > size())
- this->throw_out_of_range();
- const size_type len = min_value(n, size() - pos);
- Traits::copy(s, detail::get_pointer(this->priv_addr() + pos), len);
- return len;
- }
-
- //! <b>Effects</b>: Swaps the contents of two strings.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_string> x)
- { this->swap(x.get()); }
- void swap(basic_string& x)
- #else
- void swap(basic_string &&x)
- #endif
- { base_t::swap(x); }
-
- //! <b>Returns</b>: Returns a pointer to a null-terminated array of characters
- //! representing the string's contents. For any string s it is guaranteed
- //! that the first s.size() characters in the array pointed to by s.c_str()
- //! are equal to the character in s, and that s.c_str()[s.size()] is a null
- //! character. Note, however, that it not necessarily the first null character.
- //! Characters within a string are permitted to be null.
- const CharT* c_str() const
- { return detail::get_pointer(this->priv_addr()); }
-
- //! <b>Returns</b>: Returns a pointer to an array of characters, not necessarily
- //! null-terminated, representing the string's contents. data() is permitted,
- //! but not required, to be identical to c_str(). The first size() characters
- //! of that array are guaranteed to be identical to the characters in *this.
- //! The return value of data() is never a null pointer, even if size() is zero.
- const CharT* data() const
- { return detail::get_pointer(this->priv_addr()); }
-
- //! <b>Effects</b>: Searches for s as a substring of *this, beginning at
- //! character pos of *this.
- size_type find(const basic_string& s, size_type pos = 0) const
- { return find(s.c_str(), pos, s.size()); }
-
- //! <b>Effects</b>: Searches for a null-terminated character array as a
- //! substring of *this, beginning at character pos of *this.
- size_type find(const CharT* s, size_type pos = 0) const
- { return find(s, pos, Traits::length(s)); }
-
- //! <b>Effects</b>: Searches for the first n characters of s as a substring
- //! of *this, beginning at character pos of *this.
- size_type find(const CharT* s, size_type pos, size_type n) const
- {
- if (pos + n > size())
- return npos;
- else {
- pointer finish = this->priv_addr() + this->priv_size();
- const const_iterator result =
- std::search(detail::get_pointer(this->priv_addr() + pos),
- detail::get_pointer(finish),
- s, s + n, Eq_traits<Traits>());
- return result != finish ? result - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches for the character c, beginning at character
- //! position pos.
- size_type find(CharT c, size_type pos = 0) const
- {
- if (pos >= size())
- return npos;
- else {
- pointer finish = this->priv_addr() + this->priv_size();
- const const_iterator result =
- std::find_if(this->priv_addr() + pos, finish,
- std::bind2nd(Eq_traits<Traits>(), c));
- return result != finish ? result - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches backward for s as a substring of *this,
- //! beginning at character position min(pos, size())
- size_type rfind(const basic_string& s, size_type pos = npos) const
- { return rfind(s.c_str(), pos, s.size()); }
-
- //! <b>Effects</b>: Searches backward for a null-terminated character array
- //! as a substring of *this, beginning at character min(pos, size())
- size_type rfind(const CharT* s, size_type pos = npos) const
- { return rfind(s, pos, Traits::length(s)); }
-
- //! <b>Effects</b>: Searches backward for the first n characters of s as a
- //! substring of *this, beginning at character position min(pos, size()).
- size_type rfind(const CharT* s, size_type pos, size_type n) const
- {
- const std::size_t len = size();
-
- if (n > len)
- return npos;
- else if (n == 0)
- return min_value(len, pos);
- else {
- const const_iterator last = begin() + min_value(len - n, pos) + n;
- const const_iterator result = find_end(begin(), last,
- s, s + n,
- Eq_traits<Traits>());
- return result != last ? result - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches backward for a null-terminated character array
- //! as a substring of *this, beginning at character min(pos, size()).
- size_type rfind(CharT c, size_type pos = npos) const
- {
- const size_type len = size();
-
- if (len < 1)
- return npos;
- else {
- const const_iterator last = begin() + min_value(len - 1, pos) + 1;
- const_reverse_iterator rresult =
- std::find_if(const_reverse_iterator(last), rend(),
- std::bind2nd(Eq_traits<Traits>(), c));
- return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is equal to any character within s.
- size_type find_first_of(const basic_string& s, size_type pos = 0) const
- { return find_first_of(s.c_str(), pos, s.size()); }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is equal to any character within s.
- size_type find_first_of(const CharT* s, size_type pos = 0) const
- { return find_first_of(s, pos, Traits::length(s)); }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is equal to any character within the first n characters of s.
- size_type find_first_of(const CharT* s, size_type pos,
- size_type n) const
- {
- if (pos >= size())
- return npos;
- else {
- pointer finish = this->priv_addr() + this->priv_size();
- const_iterator result = std::find_first_of(this->priv_addr() + pos, finish,
- s, s + n,
- Eq_traits<Traits>());
- return result != finish ? result - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is equal to c.
- size_type find_first_of(CharT c, size_type pos = 0) const
- { return find(c, pos); }
-
- //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
- //! for the first character that is equal to any character within s.
- size_type find_last_of(const basic_string& s,
- size_type pos = npos) const
- { return find_last_of(s.c_str(), pos, s.size()); }
-
- //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()), for
- //! the first character that is equal to any character within s.
- size_type find_last_of(const CharT* s, size_type pos = npos) const
- { return find_last_of(s, pos, Traits::length(s)); }
-
- //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
- //! for the first character that is equal to any character within the first n
- //! characters of s.
- size_type find_last_of(const CharT* s, size_type pos, size_type n) const
- {
- const size_type len = size();
-
- if (len < 1)
- return npos;
- else {
- const const_iterator last = this->priv_addr() + min_value(len - 1, pos) + 1;
- const const_reverse_iterator rresult =
- std::find_first_of(const_reverse_iterator(last), rend(),
- s, s + n,
- Eq_traits<Traits>());
- return rresult != rend() ? (rresult.base() - 1) - this->priv_addr() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()), for
- //! the first character that is equal to c.
- size_type find_last_of(CharT c, size_type pos = npos) const
- { return rfind(c, pos); }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is not equal to any character within s.
- size_type find_first_not_of(const basic_string& s,
- size_type pos = 0) const
- { return find_first_not_of(s.c_str(), pos, s.size()); }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is not equal to any character within s.
- size_type find_first_not_of(const CharT* s, size_type pos = 0) const
- { return find_first_not_of(s, pos, Traits::length(s)); }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is not equal to any character within the first n
- //! characters of s.
- size_type find_first_not_of(const CharT* s, size_type pos,
- size_type n) const
- {
- if (pos > size())
- return npos;
- else {
- pointer finish = this->priv_addr() + this->priv_size();
- const_iterator result = std::find_if(this->priv_addr() + pos, finish,
- Not_within_traits<Traits>(s, s + n));
- return result != finish ? result - this->priv_addr() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches within *this, beginning at pos, for the first
- //! character that is not equal to c.
- size_type find_first_not_of(CharT c, size_type pos = 0) const
- {
- if (pos > size())
- return npos;
- else {
- pointer finish = this->priv_addr() + this->priv_size();
- const_iterator result
- = std::find_if(this->priv_addr() + pos, finish,
- std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
- return result != finish ? result - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
- //! for the first character that is not equal to any character within s.
- size_type find_last_not_of(const basic_string& s,
- size_type pos = npos) const
- { return find_last_not_of(s.c_str(), pos, s.size()); }
-
- //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()),
- //! for the first character that is not equal to any character within s.
- size_type find_last_not_of(const CharT* s, size_type pos = npos) const
- { return find_last_not_of(s, pos, Traits::length(s)); }
-
- //! <b>Effects</b>: Searches backward within *this, beginning at min(pos, size()),
- //! for the first character that is not equal to any character within the first
- //! n characters of s.
- size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
- {
- const size_type len = size();
-
- if (len < 1)
- return npos;
- else {
- const const_iterator last = begin() + min_value(len - 1, pos) + 1;
- const const_reverse_iterator rresult =
- std::find_if(const_reverse_iterator(last), rend(),
- Not_within_traits<Traits>(s, s + n));
- return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Searches backward *this, beginning at min(pos, size()),
- //! for the first character that is not equal to c.
- size_type find_last_not_of(CharT c, size_type pos = npos) const
- {
- const size_type len = size();
-
- if (len < 1)
- return npos;
- else {
- const const_iterator last = begin() + min_value(len - 1, pos) + 1;
- const_reverse_iterator rresult =
- std::find_if(const_reverse_iterator(last), rend(),
- std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
- return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
- }
- }
-
- //! <b>Effects</b>: Returns a substring of *this.
- basic_string substr(size_type pos = 0, size_type n = npos) const
- {
- if (pos > size())
- this->throw_out_of_range();
- return basic_string(this->priv_addr() + pos,
- this->priv_addr() + pos + min_value(n, size() - pos), this->alloc());
- }
-
- //! <b>Effects</b>: Three-way lexicographical comparison of s and *this.
- int compare(const basic_string& s) const
- { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s.priv_addr(), s.priv_addr() + s.priv_size()); }
-
- //! <b>Effects</b>: Three-way lexicographical comparison of s and a substring
- //! of *this.
- int compare(size_type pos1, size_type n1, const basic_string& s) const
- {
- if (pos1 > size())
- this->throw_out_of_range();
- return s_compare(this->priv_addr() + pos1,
- this->priv_addr() + pos1 + min_value(n1, size() - pos1),
- s.priv_addr(), s.priv_addr() + s.priv_size());
- }
-
- //! <b>Effects</b>: Three-way lexicographical comparison of a substring of s
- //! and a substring of *this.
- int compare(size_type pos1, size_type n1,
- const basic_string& s,
- size_type pos2, size_type n2) const {
- if (pos1 > size() || pos2 > s.size())
- this->throw_out_of_range();
- return s_compare(this->priv_addr() + pos1,
- this->priv_addr() + pos1 + min_value(n1, size() - pos1),
- s.priv_addr() + pos2,
- s.priv_addr() + pos2 + min_value(n2, size() - pos2));
- }
-
- //! <b>Effects</b>: Three-way lexicographical comparison of s and *this.
- int compare(const CharT* s) const
- { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s, s + Traits::length(s)); }
-
-
- //! <b>Effects</b>: Three-way lexicographical comparison of the first
- //! min(len, traits::length(s) characters of s and a substring of *this.
- int compare(size_type pos1, size_type n1, const CharT* s,
- size_type n2 = npos) const
- {
- if (pos1 > size())
- this->throw_out_of_range();
- return s_compare(this->priv_addr() + pos1,
- this->priv_addr() + pos1 + min_value(n1, size() - pos1),
- s, s + n2);
- }
-
- /// @cond
- private:
- static int s_compare(const_pointer f1, const_pointer l1,
- const_pointer f2, const_pointer l2)
- {
- const std::ptrdiff_t n1 = l1 - f1;
- const std::ptrdiff_t n2 = l2 - f2;
- const int cmp = Traits::compare(detail::get_pointer(f1),
- detail::get_pointer(f2),
- min_value(n1, n2));
- return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
- }
-
- void priv_construct_null(pointer p)
- { this->construct(p, 0); }
-
- static CharT priv_null()
- { return (CharT) 0; }
-
- // Helper functions used by constructors. It is a severe error for
- // any of them to be called anywhere except from within constructors.
- void priv_terminate_string()
- { this->priv_construct_null(this->priv_addr() + this->priv_size()); }
-
- template <class InputIter>
- void priv_range_initialize(InputIter f, InputIter l,
- std::input_iterator_tag)
- {
- this->allocate_initial_block(InternalBufferChars);
- this->priv_construct_null(this->priv_addr() + this->priv_size());
- this->append(f, l);
- }
-
- template <class ForwardIter>
- void priv_range_initialize(ForwardIter f, ForwardIter l,
- std::forward_iterator_tag)
- {
- difference_type n = std::distance(f, l);
- this->allocate_initial_block(max_value<difference_type>(n+1, InternalBufferChars));
- priv_uninitialized_copy(f, l, this->priv_addr());
- this->priv_size(n);
- this->priv_terminate_string();
- }
-
- template <class InputIter>
- void priv_range_initialize(InputIter f, InputIter l)
- {
- typedef typename std::iterator_traits<InputIter>::iterator_category Category;
- this->priv_range_initialize(f, l, Category());
- }
-
- template <class Integer>
- void priv_initialize_dispatch(Integer n, Integer x, detail::true_)
- {
- this->allocate_initial_block(max_value<difference_type>(n+1, InternalBufferChars));
- priv_uninitialized_fill_n(this->priv_addr(), n, x);
- this->priv_size(n);
- this->priv_terminate_string();
- }
-
- template <class InputIter>
- void priv_initialize_dispatch(InputIter f, InputIter l, detail::false_)
- { this->priv_range_initialize(f, l); }
-
- template<class FwdIt, class Count> inline
- void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
- {
- //Save initial position
- FwdIt init = first;
-
- BOOST_TRY{
- //Construct objects
- for (; count--; ++first){
- this->construct(first, val);
- }
- }
- BOOST_CATCH(...){
- //Call destructors
- for (; init != first; ++init){
- this->destroy(init);
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- template<class InpIt, class FwdIt> inline
- size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
- {
- //Save initial destination position
- FwdIt dest_init = dest;
- size_type constructed = 0;
-
- BOOST_TRY{
- //Try to build objects
- for (; first != last; ++dest, ++first, ++constructed){
- this->construct(dest, *first);
- }
- }
- BOOST_CATCH(...){
- //Call destructors
- for (; constructed--; ++dest_init){
- this->destroy(dest_init);
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- return (constructed);
- }
-
- template <class Integer>
- basic_string& priv_assign_dispatch(Integer n, Integer x, detail::true_)
- { return this->assign((size_type) n, (CharT) x); }
-
- template <class InputIter>
- basic_string& priv_assign_dispatch(InputIter f, InputIter l,
- detail::false_)
- {
- size_type cur = 0;
- CharT *ptr = detail::get_pointer(this->priv_addr());
- while (f != l && cur != this->priv_size()) {
- Traits::assign(*ptr, *f);
- ++f;
- ++cur;
- ++ptr;
- }
- if (f == l)
- this->erase(this->priv_addr() + cur, this->priv_addr() + this->priv_size());
- else
- this->append(f, l);
- return *this;
- }
-
- template <class InputIter>
- void priv_insert(iterator p, InputIter first, InputIter last, std::input_iterator_tag)
- {
- for ( ; first != last; ++first, ++p) {
- p = this->insert(p, *first);
- }
- }
-
- template <class ForwardIter>
- void priv_insert(iterator position, ForwardIter first,
- ForwardIter last, std::forward_iterator_tag)
- {
- if (first != last) {
- size_type n = std::distance(first, last);
- size_type remaining = this->capacity() - this->priv_size();
- const size_type old_size = this->size();
- pointer old_start = this->priv_addr();
- bool enough_capacity = false;
- std::pair<pointer, bool> allocation_ret;
- size_type new_cap = 0;
-
- //Check if we have enough capacity
- if (remaining >= n){
- enough_capacity = true;
- }
- else {
- //Otherwise expand current buffer or allocate new storage
- new_cap = this->next_capacity(n);
- allocation_ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
- new_cap, new_cap, old_start);
-
- //Check forward expansion
- if(old_start == allocation_ret.first){
- enough_capacity = true;
- this->priv_storage(new_cap);
- }
- }
-
- //Reuse same buffer
- if(enough_capacity){
- const size_type elems_after =
- this->priv_size() - (position - this->priv_addr());
- size_type old_length = this->priv_size();
- if (elems_after >= n) {
- pointer pointer_past_last = this->priv_addr() + this->priv_size() + 1;
- priv_uninitialized_copy(this->priv_addr() + (this->priv_size() - n + 1),
- pointer_past_last, pointer_past_last);
-
- this->priv_size(this->priv_size()+n);
- Traits::move(detail::get_pointer(position + n),
- detail::get_pointer(position),
- (elems_after - n) + 1);
- this->priv_copy(first, last, position);
- }
- else {
- ForwardIter mid = first;
- std::advance(mid, elems_after + 1);
-
- priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1);
- this->priv_size(this->priv_size() + (n - elems_after));
- priv_uninitialized_copy
- (position, this->priv_addr() + old_length + 1,
- this->priv_addr() + this->priv_size());
- this->priv_size(this->priv_size() + elems_after);
- this->priv_copy(first, mid, position);
- }
- }
- else{
- pointer new_start = allocation_ret.first;
- if(!allocation_ret.second){
- //Copy data to new buffer
- size_type new_length = 0;
- //This can't throw, since characters are POD
- new_length += priv_uninitialized_copy
- (this->priv_addr(), position, new_start);
- new_length += priv_uninitialized_copy
- (first, last, new_start + new_length);
- new_length += priv_uninitialized_copy
- (position, this->priv_addr() + this->priv_size(),
- new_start + new_length);
- this->priv_construct_null(new_start + new_length);
-
- this->deallocate_block();
- this->is_short(false);
- this->priv_addr(new_start);
- this->priv_size(new_length);
- this->priv_storage(new_cap);
- }
- else{
- //value_type is POD, so backwards expansion is much easier
- //than with vector<T>
- value_type *oldbuf = detail::get_pointer(old_start);
- value_type *newbuf = detail::get_pointer(new_start);
- value_type *pos = detail::get_pointer(position);
- size_type before = pos - oldbuf;
-
- //First move old data
- Traits::move(newbuf, oldbuf, before);
- Traits::move(newbuf + before + n, pos, old_size - before);
- //Now initialize the new data
- priv_uninitialized_copy(first, last, new_start + before);
- this->priv_construct_null(new_start + (old_size + n));
- this->is_short(false);
- this->priv_addr(new_start);
- this->priv_size(old_size + n);
- this->priv_storage(new_cap);
- }
- }
- }
- }
-
- template <class Integer>
- void priv_insert_dispatch(iterator p, Integer n, Integer x,
- detail::true_)
- { insert(p, (size_type) n, (CharT) x); }
-
- template <class InputIter>
- void priv_insert_dispatch(iterator p, InputIter first, InputIter last,
- detail::false_)
- {
- typedef typename std::iterator_traits<InputIter>::iterator_category Category;
- priv_insert(p, first, last, Category());
- }
-
- template <class InputIterator>
- void priv_copy(InputIterator first, InputIterator last, iterator result)
- {
- for ( ; first != last; ++first, ++result)
- Traits::assign(*result, *first);
- }
-
- void priv_copy(const CharT* first, const CharT* last, CharT* result)
- { Traits::copy(result, first, last - first); }
-
- template <class Integer>
- basic_string& priv_replace_dispatch(iterator first, iterator last,
- Integer n, Integer x,
- detail::true_)
- { return this->replace(first, last, (size_type) n, (CharT) x); }
-
- template <class InputIter>
- basic_string& priv_replace_dispatch(iterator first, iterator last,
- InputIter f, InputIter l,
- detail::false_)
- {
- typedef typename std::iterator_traits<InputIter>::iterator_category Category;
- return this->priv_replace(first, last, f, l, Category());
- }
-
-
- template <class InputIter>
- basic_string& priv_replace(iterator first, iterator last,
- InputIter f, InputIter l, std::input_iterator_tag)
- {
- for ( ; first != last && f != l; ++first, ++f)
- Traits::assign(*first, *f);
-
- if (f == l)
- this->erase(first, last);
- else
- this->insert(last, f, l);
- return *this;
- }
-
- template <class ForwardIter>
- basic_string& priv_replace(iterator first, iterator last,
- ForwardIter f, ForwardIter l,
- std::forward_iterator_tag)
- {
- difference_type n = std::distance(f, l);
- const difference_type len = last - first;
- if (len >= n) {
- this->priv_copy(f, l, first);
- this->erase(first + n, last);
- }
- else {
- ForwardIter m = f;
- std::advance(m, len);
- this->priv_copy(f, m, first);
- this->insert(last, m, l);
- }
- return *this;
- }
- /// @endcond
-};
-
-template <class CharT, class Traits, class A>
-const typename basic_string<CharT,Traits,A>::size_type
-basic_string<CharT,Traits,A>::npos
- = (typename basic_string<CharT,Traits,A>::size_type) -1;
-
-// ------------------------------------------------------------
-// Non-member functions.
-
-// Operator+
-
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A>
-operator+(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y)
-{
- typedef basic_string<CharT,Traits,A> str_t;
- typedef typename str_t::reserve_t reserve_t;
- reserve_t reserve;
- str_t result(reserve, x.size() + y.size(), x.alloc());
- result.append(x);
- result.append(y);
- return result;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(detail::moved_object<basic_string<CharT,Traits,A> > mx,
- const basic_string<CharT,Traits,A>& y)
-{
- mx.get() += y;
- return mx;
-}
-#else
-template <class CharT, class Traits, class A>
-basic_string<CharT,Traits,A> &&
-operator+(basic_string<CharT,Traits,A> && mx,
- const basic_string<CharT,Traits,A>& y)
-{
- mx += y;
- return detail::move_impl(mx);
-}
-#endif
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(const basic_string<CharT,Traits,A>& x,
- detail::moved_object<basic_string<CharT,Traits,A> > my)
-{
- typedef typename basic_string<CharT,Traits,A>::size_type size_type;
- return my.get().replace(size_type(0), size_type(0), x);
-}
-#else
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A> &&
-operator+(const basic_string<CharT,Traits,A>& x,
- basic_string<CharT,Traits,A> && my)
-{
- typedef typename basic_string<CharT,Traits,A>::size_type size_type;
- return my.replace(size_type(0), size_type(0), x);
-}
-#endif
-
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A>
-operator+(const CharT* s, const basic_string<CharT,Traits,A>& y)
-{
- typedef basic_string<CharT,Traits,A> str_t;
- typedef typename str_t::reserve_t reserve_t;
- reserve_t reserve;
- const std::size_t n = Traits::length(s);
- str_t result(reserve, n + y.size());
- result.append(s, s + n);
- result.append(y);
- return result;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(const CharT* s,
- detail::moved_object<basic_string<CharT,Traits,A> > my)
-{
- typedef typename basic_string<CharT,Traits,A>::size_type size_type;
- return my.get().replace(size_type(0), size_type(0), s);
-}
-#else
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A> &&
-operator+(const CharT* s,
- basic_string<CharT,Traits,A> && my)
-{
- typedef typename basic_string<CharT,Traits,A>::size_type size_type;
- return detail::move_impl(my.get().replace(size_type(0), size_type(0), s));
-}
-#endif
-
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A>
-operator+(CharT c, const basic_string<CharT,Traits,A>& y)
-{
- typedef basic_string<CharT,Traits,A> str_t;
- typedef typename str_t::reserve_t reserve_t;
- reserve_t reserve;
- str_t result(reserve, 1 + y.size());
- result.push_back(c);
- result.append(y);
- return result;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(CharT c,
- detail::moved_object<basic_string<CharT,Traits,A> > my)
-{
- typedef typename basic_string<CharT,Traits,A>::size_type size_type;
- return my.get().replace(size_type(0), size_type(0), &c, &c + 1);
-}
-#else
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A> &&
-operator+(CharT c,
- basic_string<CharT,Traits,A> && my)
-{
- typedef typename basic_string<CharT,Traits,A>::size_type size_type;
- return my.replace(size_type(0), size_type(0), &c, &c + 1);
-}
-#endif
-
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A>
-operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
-{
- typedef basic_string<CharT,Traits,A> str_t;
- typedef typename str_t::reserve_t reserve_t;
- reserve_t reserve;
- const std::size_t n = Traits::length(s);
- str_t result(reserve, x.size() + n, x.alloc());
- result.append(x);
- result.append(s, s + n);
- return result;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(detail::moved_object<basic_string<CharT,Traits,A> > mx,
- const CharT* s)
-{
- mx.get() += s;
- return mx;
-}
-#else
-template <class CharT, class Traits, class A>
-basic_string<CharT,Traits,A> &&
-operator+(basic_string<CharT,Traits,A> && mx,
- const CharT* s)
-{
- mx += s;
- return detail::move_impl(mx);
-}
-#endif
-
-template <class CharT, class Traits, class A>
-inline basic_string<CharT,Traits,A>
-operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
-{
- typedef basic_string<CharT,Traits,A> str_t;
- typedef typename str_t::reserve_t reserve_t;
- reserve_t reserve;
- str_t result(reserve, x.size() + 1, x.alloc());
- result.append(x);
- result.push_back(c);
- return result;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(detail::moved_object<basic_string<CharT,Traits,A> > mx,
- const CharT c)
-{
- mx.get() += c;
- return mx;
-}
-#else
-template <class CharT, class Traits, class A>
-basic_string<CharT,Traits,A> &&
-operator+(basic_string<CharT,Traits,A> && mx, const CharT c)
-{
- mx += c;
- return detail::move_impl(mx);
-}
-#endif
-
-// Operator== and operator!=
-
-template <class CharT, class Traits, class A>
-inline bool
-operator==(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y)
-{
- return x.size() == y.size() &&
- Traits::compare(x.data(), y.data(), x.size()) == 0;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator==(const CharT* s, const basic_string<CharT,Traits,A>& y)
-{
- std::size_t n = Traits::length(s);
- return n == y.size() && Traits::compare(s, y.data(), n) == 0;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator==(const basic_string<CharT,Traits,A>& x, const CharT* s)
-{
- std::size_t n = Traits::length(s);
- return x.size() == n && Traits::compare(x.data(), s, n) == 0;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator!=(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y)
- { return !(x == y); }
-
-template <class CharT, class Traits, class A>
-inline bool
-operator!=(const CharT* s, const basic_string<CharT,Traits,A>& y)
- { return !(s == y); }
-
-template <class CharT, class Traits, class A>
-inline bool
-operator!=(const basic_string<CharT,Traits,A>& x, const CharT* s)
- { return !(x == s); }
-
-
-// Operator< (and also >, <=, and >=).
-
-template <class CharT, class Traits, class A>
-inline bool
-operator<(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y)
-{
- return x.compare(y) < 0;
-// return basic_string<CharT,Traits,A>
-// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator<(const CharT* s, const basic_string<CharT,Traits,A>& y)
-{
- return y.compare(s) > 0;
-// std::size_t n = Traits::length(s);
-// return basic_string<CharT,Traits,A>
-// ::s_compare(s, s + n, y.begin(), y.end()) < 0;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator<(const basic_string<CharT,Traits,A>& x,
- const CharT* s)
-{
- return x.compare(s) < 0;
-// std::size_t n = Traits::length(s);
-// return basic_string<CharT,Traits,A>
-// ::s_compare(x.begin(), x.end(), s, s + n) < 0;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator>(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y) {
- return y < x;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator>(const CharT* s, const basic_string<CharT,Traits,A>& y) {
- return y < s;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator>(const basic_string<CharT,Traits,A>& x, const CharT* s)
-{
- return s < x;
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator<=(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y)
-{
- return !(y < x);
-}
-
-template <class CharT, class Traits, class A>
-inline bool
-operator<=(const CharT* s, const basic_string<CharT,Traits,A>& y)
- { return !(y < s); }
-
-template <class CharT, class Traits, class A>
-inline bool
-operator<=(const basic_string<CharT,Traits,A>& x, const CharT* s)
- { return !(s < x); }
-
-template <class CharT, class Traits, class A>
-inline bool
-operator>=(const basic_string<CharT,Traits,A>& x,
- const basic_string<CharT,Traits,A>& y)
- { return !(x < y); }
-
-template <class CharT, class Traits, class A>
-inline bool
-operator>=(const CharT* s, const basic_string<CharT,Traits,A>& y)
- { return !(s < y); }
-
-template <class CharT, class Traits, class A>
-inline bool
-operator>=(const basic_string<CharT,Traits,A>& x, const CharT* s)
- { return !(x < s); }
-
-// Swap.
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>& y)
-{ x.swap(y); }
-
-template <class CharT, class Traits, class A>
-inline void swap(detail::moved_object<basic_string<CharT,Traits,A> > mx, basic_string<CharT,Traits,A>& y)
-{ mx.get().swap(y); }
-
-template <class CharT, class Traits, class A>
-inline void swap(basic_string<CharT,Traits,A>& x, detail::moved_object<basic_string<CharT,Traits,A> > my)
-{ x.swap(my.get()); }
-#else
-template <class CharT, class Traits, class A>
-inline void swap(basic_string<CharT,Traits,A> && x, basic_string<CharT,Traits,A> &&y)
-{ x.swap(y); }
-#endif
-
-/// @cond
-// I/O.
-namespace detail {
-
-template <class CharT, class Traits>
-inline bool
-interprocess_string_fill(std::basic_ostream<CharT, Traits>& os,
- std::basic_streambuf<CharT, Traits>* buf,
- std::size_t n)
-{
- CharT f = os.fill();
- std::size_t i;
- bool ok = true;
-
- for (i = 0; i < n; i++)
- ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
- return ok;
-}
-
-} //namespace detail {
-/// @endcond
-
-template <class CharT, class Traits, class A>
-std::basic_ostream<CharT, Traits>&
-operator<<(std::basic_ostream<CharT, Traits>& os,
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- const basic_string<CharT,Traits,A>& s)
- #else
- const basic_string<CharT,Traits,A>&&s)
- #endif
-{
- typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
- bool ok = false;
-
- if (sentry) {
- ok = true;
- std::size_t n = s.size();
- std::size_t pad_len = 0;
- const bool left = (os.flags() & std::ios::left) != 0;
- const std::size_t w = os.width(0);
- std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
-
- if (w != 0 && n < w)
- pad_len = w - n;
-
- if (!left)
- ok = detail::interprocess_string_fill(os, buf, pad_len);
-
- ok = ok &&
- buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
-
- if (left)
- ok = ok && detail::interprocess_string_fill(os, buf, pad_len);
- }
-
- if (!ok)
- os.setstate(std::ios_base::failbit);
-
- return os;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-std::basic_ostream<CharT, Traits>&
-operator<<(std::basic_ostream<CharT, Traits>& os,
- detail::moved_object<basic_string<CharT,Traits,A> > ms)
-{ return os << ms.get(); }
-#endif
-
-
-template <class CharT, class Traits, class A>
-std::basic_istream<CharT, Traits>&
-operator>>(std::basic_istream<CharT, Traits>& is,
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_string<CharT,Traits,A>& s)
- #else
- basic_string<CharT,Traits,A>&&s)
- #endif
-{
- typename std::basic_istream<CharT, Traits>::sentry sentry(is);
-
- if (sentry) {
- std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
- const std::ctype<CharT>& ctype = std::use_facet<std::ctype<CharT> >(is.getloc());
-
- s.clear();
- std::size_t n = is.width(0);
- if (n == 0)
- n = static_cast<std::size_t>(-1);
- else
- s.reserve(n);
-
- while (n-- > 0) {
- typename Traits::int_type c1 = buf->sbumpc();
-
- if (Traits::eq_int_type(c1, Traits::eof())) {
- is.setstate(std::ios_base::eofbit);
- break;
- }
- else {
- CharT c = Traits::to_char_type(c1);
-
- if (ctype.is(std::ctype<CharT>::space, c)) {
- if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof()))
- is.setstate(std::ios_base::failbit);
- break;
- }
- else
- s.push_back(c);
- }
- }
-
- // If we have read no characters, then set failbit.
- if (s.size() == 0)
- is.setstate(std::ios_base::failbit);
- }
- else
- is.setstate(std::ios_base::failbit);
-
- return is;
-}
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class CharT, class Traits, class A>
-std::basic_istream<CharT, Traits>&
-operator>>(std::basic_istream<CharT, Traits>& is,
- detail::moved_object<basic_string<CharT,Traits,A> > ms)
-{ return is >> ms.get(); }
-#endif
-
-template <class CharT, class Traits, class A>
-std::basic_istream<CharT, Traits>&
-getline(std::istream& is,
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_string<CharT,Traits,A>& s,
- #else
- basic_string<CharT,Traits,A>&&s,
- #endif
- CharT delim)
-{
- std::size_t nread = 0;
- typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
- if (sentry) {
- std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
- s.clear();
-
- int c1;
- while (nread < s.max_size()) {
- int c1 = buf->sbumpc();
- if (Traits::eq_int_type(c1, Traits::eof())) {
- is.setstate(std::ios_base::eofbit);
- break;
- }
- else {
- ++nread;
- CharT c = Traits::to_char_type(c1);
- if (!Traits::eq(c, delim))
- s.push_back(c);
- else
- break; // Character is extracted but not appended.
- }
- }
- }
- if (nread == 0 || nread >= s.max_size())
- is.setstate(std::ios_base::failbit);
-
- return is;
-}
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class CharT, class Traits, class A>
-std::basic_istream<CharT, Traits>&
-getline(std::istream& is,
- detail::moved_object<basic_string<CharT,Traits,A> > ms,
- CharT delim)
-{ return getline(is, ms.get(), delim); }
-#endif
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class CharT, class Traits, class A>
-inline std::basic_istream<CharT, Traits>&
-getline(std::basic_istream<CharT, Traits>& is,
- basic_string<CharT,Traits,A>& s)
-{
- return getline(is, s, '\n');
-}
-
-template <class CharT, class Traits, class A>
-std::basic_istream<CharT, Traits>&
-getline(std::istream& is,
- detail::moved_object<basic_string<CharT,Traits,A> > ms)
-{ return getline(is, ms.get()); }
-#else
-template <class CharT, class Traits, class A>
-std::basic_istream<CharT, Traits>&
-getline(std::istream& is,
- basic_string<CharT,Traits,A> && ms)
-{ return getline(is, ms); }
-#endif
-
-template <class Ch, class A>
-inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v)
-{
- return hash_range(v.begin(), v.end());
-}
-
-/// @cond
-
-//!This class is movable
-template <class C, class T, class A>
-struct is_movable<basic_string<C, T, A> >
-{
- enum { value = true };
-};
-
-//!This class is movable
-template <class A>
-struct is_movable<detail::basic_string_base<A> >
-{
- enum { value = true };
-};
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class C, class T, class A>
-struct has_trivial_destructor_after_move<basic_string<C, T, A> >
-{
- enum { value = has_trivial_destructor<A>::value };
-};
-/// @endcond
+using boost::interprocess_container::basic_string;
+using boost::interprocess_container::string;
-}} //namespace boost { namespace interprocess
+} //namespace interprocess {
+} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif // BOOST_INTERPROCESS_STRING_HPP
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_STRING_HPP
Modified: trunk/boost/interprocess/containers/vector.hpp
==============================================================================
--- trunk/boost/interprocess/containers/vector.hpp (original)
+++ trunk/boost/interprocess/containers/vector.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,1998 +1,32 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-//
-// This file comes from SGI's stl_vector.h file. Modified by Ion Gaztanaga.
-// Renaming, isolating and porting to generic algorithms. Pointer typedef
-// set to allocator::pointer to allow placing it in shared memory.
-//
-///////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 1994
-// Hewlett-Packard Company
-//
-// Permission to use, copy, modify, distribute and sell this software
-// and its documentation for any purpose is hereby granted without fee,
-// provided that the above copyright notice appear in all copies and
-// that both that copyright notice and this permission notice appear
-// in supporting documentation. Hewlett-Packard Company makes no
-// representations about the suitability of this software for any
-// purpose. It is provided "as is" without express or implied warranty.
-//
-//
-// Copyright (c) 1996
-// Silicon Graphics Computer Systems, Inc.
-//
-// Permission to use, copy, modify, distribute and sell this software
-// and its documentation for any purpose is hereby granted without fee,
-// provided that the above copyright notice appear in all copies and
-// that both that copyright notice and this permission notice appear
-// in supporting documentation. Silicon Graphics makes no
-// representations about the suitability of this software for any
-// purpose. It is provided "as is" without express or implied warranty.
-#ifndef BOOST_INTERPROCESS_VECTOR_HPP
-#define BOOST_INTERPROCESS_VECTOR_HPP
+#ifndef BOOST_INTERPROCESS_CONTAINERS_VECTOR_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_VECTOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <cstddef>
-#include <memory>
-#include <algorithm>
-#include <stdexcept>
-#include <iterator>
-#include <utility>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/type_traits/has_nothrow_copy.hpp>
-#include <boost/type_traits/has_nothrow_assign.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
-#include <boost/interprocess/detail/min_max.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/move_iterator.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/advanced_insert_int.hpp>
+#include <boost/interprocess/containers/container/vector.hpp>
namespace boost {
namespace interprocess {
-/// @cond
-
-namespace detail {
-
-//! Const vector_iterator used to iterate through a vector.
-template <class Pointer>
-class vector_const_iterator
- : public std::iterator<std::random_access_iterator_tag
- ,const typename std::iterator_traits<Pointer>::value_type
- ,typename std::iterator_traits<Pointer>::difference_type
- ,typename pointer_to_other
- <Pointer
- ,const typename std::iterator_traits<Pointer>::value_type
- >::type
- ,const typename std::iterator_traits<Pointer>::value_type &>
-{
- public:
- typedef const typename std::iterator_traits<Pointer>::value_type value_type;
- typedef typename std::iterator_traits<Pointer>::difference_type difference_type;
- typedef typename pointer_to_other<Pointer, value_type>::type pointer;
- typedef value_type& reference;
-
- /// @cond
- protected:
- Pointer m_ptr;
-
- public:
- Pointer get_ptr() const { return m_ptr; }
- explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){}
- /// @endcond
-
- public:
-
- //Constructors
- vector_const_iterator() : m_ptr(0){}
-
- //Pointer like operators
- reference operator*() const
- { return *m_ptr; }
-
- const value_type * operator->() const
- { return detail::get_pointer(m_ptr); }
-
- reference operator[](difference_type off) const
- { return m_ptr[off]; }
-
- //Increment / Decrement
- vector_const_iterator& operator++()
- { ++m_ptr; return *this; }
-
- vector_const_iterator operator++(int)
- { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); }
-
- vector_const_iterator& operator--()
- { --m_ptr; return *this; }
-
- vector_const_iterator operator--(int)
- { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); }
-
- //Arithmetic
- vector_const_iterator& operator+=(difference_type off)
- { m_ptr += off; return *this; }
-
- vector_const_iterator operator+(difference_type off) const
- { return vector_const_iterator(m_ptr+off); }
-
- friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right)
- { return vector_const_iterator(off + right.m_ptr); }
-
- vector_const_iterator& operator-=(difference_type off)
- { m_ptr -= off; return *this; }
-
- vector_const_iterator operator-(difference_type off) const
- { return vector_const_iterator(m_ptr-off); }
-
- difference_type operator-(const vector_const_iterator& right) const
- { return m_ptr - right.m_ptr; }
-
- //Comparison operators
- bool operator== (const vector_const_iterator& r) const
- { return m_ptr == r.m_ptr; }
-
- bool operator!= (const vector_const_iterator& r) const
- { return m_ptr != r.m_ptr; }
-
- bool operator< (const vector_const_iterator& r) const
- { return m_ptr < r.m_ptr; }
-
- bool operator<= (const vector_const_iterator& r) const
- { return m_ptr <= r.m_ptr; }
-
- bool operator> (const vector_const_iterator& r) const
- { return m_ptr > r.m_ptr; }
-
- bool operator>= (const vector_const_iterator& r) const
- { return m_ptr >= r.m_ptr; }
-};
-
-//! Iterator used to iterate through a vector
-template <class Pointer>
-class vector_iterator
- : public vector_const_iterator<Pointer>
-{
- public:
- explicit vector_iterator(Pointer ptr)
- : vector_const_iterator<Pointer>(ptr)
- {}
-
- public:
- typedef typename std::iterator_traits<Pointer>::value_type value_type;
- typedef typename vector_const_iterator<Pointer>::difference_type difference_type;
- typedef Pointer pointer;
- typedef value_type& reference;
-
- //Constructors
- vector_iterator()
- {}
-
- //Pointer like operators
- reference operator*() const
- { return *this->m_ptr; }
-
- value_type* operator->() const
- { return detail::get_pointer(this->m_ptr); }
-
- reference operator[](difference_type off) const
- { return this->m_ptr[off]; }
-
- //Increment / Decrement
- vector_iterator& operator++()
- { ++this->m_ptr; return *this; }
-
- vector_iterator operator++(int)
- { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); }
-
- vector_iterator& operator--()
- { --this->m_ptr; return *this; }
-
- vector_iterator operator--(int)
- { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); }
-
- // Arithmetic
- vector_iterator& operator+=(difference_type off)
- { this->m_ptr += off; return *this; }
-
- vector_iterator operator+(difference_type off) const
- { return vector_iterator(this->m_ptr+off); }
-
- friend vector_iterator operator+(difference_type off, const vector_iterator& right)
- { return vector_iterator(off + right.m_ptr); }
-
- vector_iterator& operator-=(difference_type off)
- { this->m_ptr -= off; return *this; }
-
- vector_iterator operator-(difference_type off) const
- { return vector_iterator(this->m_ptr-off); }
-
- difference_type operator-(const vector_const_iterator<Pointer>& right) const
- { return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; }
-};
-
-template <class T, class A>
-struct vector_value_traits
-{
- typedef T value_type;
- typedef A allocator_type;
- static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move =
- has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
- static const bool trivial_copy = has_trivial_copy<value_type>::value;
- static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
- static const bool trivial_assign = has_trivial_assign<value_type>::value;
- static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
-
- //This is the anti-exception array destructor
- //to deallocate values already constructed
- typedef typename detail::if_c
- <trivial_dctr
- ,detail::null_scoped_destructor_n<allocator_type>
- ,detail::scoped_destructor_n<allocator_type>
- >::type OldArrayDestructor;
- //This is the anti-exception array destructor
- //to destroy objects created with copy construction
- typedef typename detail::if_c
- <nothrow_copy
- ,detail::null_scoped_destructor_n<allocator_type>
- ,detail::scoped_destructor_n<allocator_type>
- >::type UCopiedArrayDestructor;
- //This is the anti-exception array deallocator
- typedef typename detail::if_c
- <nothrow_copy
- ,detail::null_scoped_array_deallocator<allocator_type>
- ,detail::scoped_array_deallocator<allocator_type>
- >::type UCopiedArrayDeallocator;
-
- //This is the optimized move iterator for copy constructors
- //so that std::copy and similar can use memcpy
- typedef typename detail::if_c
- <trivial_copy
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- || !is_movable<value_type>::value
- #endif
- ,const T*
- ,detail::move_iterator<T*>
- >::type copy_move_it;
-
- //This is the optimized move iterator for assignments
- //so that std::uninitialized_copy and similar can use memcpy
- typedef typename detail::if_c
- <trivial_assign
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- || !is_movable<value_type>::value
- #endif
- ,const T*
- ,detail::move_iterator<T*>
- >::type assign_move_it;
-};
-
-//!This struct deallocates and allocated memory
-template <class A>
-struct vector_alloc_holder
-{
- typedef typename A::pointer pointer;
- typedef typename A::size_type size_type;
- typedef typename A::value_type value_type;
- typedef vector_value_traits<value_type, A> value_traits;
-
- //Constructor, does not throw
- vector_alloc_holder(const A &a)
- : members_(a)
- {}
-
- //Constructor, does not throw
- vector_alloc_holder(const vector_alloc_holder<A> &h)
- : members_(h.alloc())
- {}
-
- //Destructor
- ~vector_alloc_holder()
- {
- this->prot_destroy_all();
- this->prot_deallocate();
- }
-
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
- typedef detail::integral_constant<unsigned,
- boost::interprocess::detail::version<A>::value> alloc_version;
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size, const pointer &reuse = 0)
- {
- return allocation_command(command, limit_size, preferred_size,
- received_size, reuse, alloc_version());
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v1)
- {
- (void)limit_size;
- (void)reuse;
- if(!(command & allocate_new))
- return std::pair<pointer, bool>(pointer(0), 0);
- received_size = preferred_size;
- return std::make_pair(this->alloc().allocate(received_size), false);
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v2)
- {
- return this->alloc().allocation_command
- (command, limit_size, preferred_size, received_size, reuse);
- }
-
- size_type next_capacity(size_type additional_objects) const
- { return get_next_capacity(this->alloc().max_size(), this->members_.m_capacity, additional_objects); }
-
- struct members_holder
- : public A
- {
- private:
- members_holder(const members_holder&);
-
- public:
- members_holder(const A &alloc)
- : A(alloc), m_start(0), m_size(0), m_capacity(0)
- {}
-
- pointer m_start;
- size_type m_size;
- size_type m_capacity;
- } members_;
-
- protected:
- void prot_deallocate()
- {
- if(!this->members_.m_capacity) return;
- this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
- this->members_.m_start = 0;
- this->members_.m_size = 0;
- this->members_.m_capacity = 0;
- }
-
- void destroy(value_type* p)
- {
- if(!value_traits::trivial_dctr)
- detail::get_pointer(p)->~value_type();
- }
-
- void destroy_n(value_type* p, size_type n)
- {
- if(!value_traits::trivial_dctr)
- for(; n--; ++p) p->~value_type();
- }
-
- void prot_destroy_all()
- {
- this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
- this->members_.m_size = 0;
- }
-
- A &alloc()
- { return members_; }
-
- const A &alloc() const
- { return members_; }
-};
-
-} //namespace detail {
-/// @endcond
-
-//! A vector is a sequence that supports random access to elements, constant
-//! time insertion and removal of elements at the end, and linear time insertion
-//! and removal of elements at the beginning or in the middle. The number of
-//! elements in a vector may vary dynamically; memory management is automatic.
-//! boost::interprocess::vector is similar to std::vector but it's compatible
-//! with shared memory and memory mapped files.
-template <class T, class A>
-class vector : private detail::vector_alloc_holder<A>
-{
- /// @cond
- typedef vector<T, A> self_t;
- typedef detail::vector_alloc_holder<A> base_t;
- /// @endcond
- public:
- //! The type of object, T, stored in the vector
- typedef T value_type;
- //! Pointer to T
- typedef typename A::pointer pointer;
- //! Const pointer to T
- typedef typename A::const_pointer const_pointer;
- //! Reference to T
- typedef typename A::reference reference;
- //! Const reference to T
- typedef typename A::const_reference const_reference;
- //! An unsigned integral type
- typedef typename A::size_type size_type;
- //! A signed integral type
- typedef typename A::difference_type difference_type;
- //! The allocator type
- typedef A allocator_type;
- //! The random access iterator
- typedef detail::vector_iterator<pointer> iterator;
- //! The random access const_iterator
- typedef detail::vector_const_iterator<pointer> const_iterator;
-
- //! Iterator used to iterate backwards through a vector.
- typedef std::reverse_iterator<iterator>
- reverse_iterator;
- //! Const iterator used to iterate backwards through a vector.
- typedef std::reverse_iterator<const_iterator>
- const_reverse_iterator;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
-
- /// @cond
- private:
- typedef detail::advanced_insert_aux_int<T, T*> advanced_insert_aux_int_t;
- typedef detail::vector_value_traits<value_type, A> value_traits;
-
- typedef typename base_t::allocator_v1 allocator_v1;
- typedef typename base_t::allocator_v2 allocator_v2;
- typedef typename base_t::alloc_version alloc_version;
-
- typedef constant_iterator<T, difference_type> cvalue_iterator;
- typedef repeat_iterator<T, difference_type> repeat_it;
- typedef detail::move_iterator<repeat_it> repeat_move_it;
- /// @endcond
-
- public:
-
- //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- explicit vector(const A& a = A())
- : base_t(a)
- {}
-
- //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
- //! and inserts n copies of value.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
- //! throws or T's default or copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- vector(size_type n, const T& value = T(),
- const allocator_type& a = allocator_type())
- : base_t(a)
- { this->insert(this->cend(), n, value); }
-
- //! <b>Effects</b>: Copy constructs a vector.
- //!
- //! <b>Postcondition</b>: x == *this.
- //!
- //! <b>Complexity</b>: Linear to the elements x contains.
- vector(const vector<T, A>& x)
- : base_t((base_t&)x)
- { *this = x; }
-
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- vector(detail::moved_object<vector<T, A> > mx)
- : base_t(mx.get())
- { this->swap(mx.get()); }
- #else
- vector(vector<T, A> && mx)
- : base_t(detail::move_impl(mx))
- { this->swap(mx); }
- #endif
-
- //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
- //! and inserts a copy of the range [first, last) in the vector.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
- //! throws or T's constructor taking an dereferenced InIt throws.
- //!
- //! <b>Complexity</b>: Linear to the range [first, last).
- template <class InIt>
- vector(InIt first, InIt last, const allocator_type& a = allocator_type())
- : base_t(a)
- { this->assign(first, last); }
-
- //! <b>Effects</b>: Destroys the vector. All stored values are destroyed
- //! and used memory is deallocated.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements.
- ~vector()
- {} //vector_alloc_holder clears the data
-
- //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator begin()
- { return iterator(this->members_.m_start); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return const_iterator(this->members_.m_start); }
-
- //! <b>Effects</b>: Returns an iterator to the end of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator end()
- { return iterator(this->members_.m_start + this->members_.m_size); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator end() const
- { return this->cend(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
- { return reverse_iterator(this->end()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin()const
- { return this->crbegin(); }
-
- //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reverse_iterator rend()
- { return reverse_iterator(this->begin()); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
- { return this->crend(); }
-
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
- { return const_iterator(this->members_.m_start); }
-
- //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_iterator cend() const
- { return const_iterator(this->members_.m_start + this->members_.m_size); }
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin()const
- { return const_reverse_iterator(this->end());}
-
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return const_reverse_iterator(this->begin()); }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference front()
- { return *this->members_.m_start; }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference front() const
- { return *this->members_.m_start; }
-
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference back()
- { return this->members_.m_start[this->members_.m_size - 1]; }
-
- //! <b>Effects</b>: Returns a const reference to the first element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference back() const
- { return this->members_.m_start[this->members_.m_size - 1]; }
-
- //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
- //! For a non-empty vector, data() == &front().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- pointer data()
- { return this->members_.m_start; }
-
- //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
- //! For a non-empty vector, data() == &front().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_pointer data() const
- { return this->members_.m_start; }
-
- //! <b>Effects</b>: Returns the number of the elements contained in the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type size() const
- { return this->members_.m_size; }
-
- //! <b>Effects</b>: Returns the largest possible size of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const
- { return this->alloc().max_size(); }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return this->members_.m_capacity; }
-
- //! <b>Effects</b>: Returns true if the vector contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->members_.m_size; }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
- { return this->members_.m_start[n]; }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a const reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const
- { return this->members_.m_start[n]; }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: std::range_error if n >= size()
- //!
- //! <b>Complexity</b>: Constant.
- reference at(size_type n)
- { this->priv_check_range(n); return this->members_.m_start[n]; }
-
- //! <b>Requires</b>: size() < n.
- //!
- //! <b>Effects</b>: Returns a const reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: std::range_error if n >= size()
- //!
- //! <b>Complexity</b>: Constant.
- const_reference at(size_type n) const
- { this->priv_check_range(n); return this->members_.m_start[n]; }
-
- //! <b>Effects</b>: Returns a copy of the internal allocator.
- //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return this->alloc(); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return this->alloc(); }
-
- stored_allocator_type &get_stored_allocator()
- { return this->alloc(); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
- //!
- //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
- void reserve(size_type new_cap)
- {
- if (this->capacity() < new_cap){
- //There is not enough memory, allocate a new
- //buffer or expand the old one.
- bool same_buffer_start;
- size_type real_cap = 0;
- std::pair<pointer, bool> ret =
- this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- new_cap, new_cap, real_cap, this->members_.m_start);
-
- //Check for forward expansion
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_expand_fwd;
- #endif
- this->members_.m_capacity = real_cap;
- }
- //If there is no forward expansion, move objects
- else{
- //We will reuse insert code, so create a dummy input iterator
- typename value_traits::copy_move_it dummy_it(detail::get_pointer(this->members_.m_start));
- detail::advanced_insert_aux_proxy<T, typename value_traits::copy_move_it, T*>
- proxy(dummy_it, dummy_it);
- //Backwards (and possibly forward) expansion
- if(ret.second){
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_expand_bwd;
- #endif
- this->priv_range_insert_expand_backwards
- ( detail::get_pointer(ret.first)
- , real_cap
- , detail::get_pointer(this->members_.m_start)
- , 0
- , proxy);
- }
- //New buffer
- else{
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_alloc;
- #endif
- this->priv_range_insert_new_allocation
- ( detail::get_pointer(ret.first)
- , real_cap
- , detail::get_pointer(this->members_.m_start)
- , 0
- , proxy);
- }
- }
- }
- }
-
- //! <b>Effects</b>: Makes *this contain the same elements as x.
- //!
- //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
- //! of each of x's elements.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in x.
- vector<T, A>& operator=(const vector<T, A>& x)
- {
- if (&x != this){
- this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size);
- }
- return *this;
- }
-
- //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
- //!
- //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
- //! before the function.
- //!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- vector<T, A>& operator=(detail::moved_object<vector<T, A> > mx)
- {
- vector<T, A> &x = mx.get();
- #else
- vector<T, A>& operator=(vector<T, A> && x)
- {
- #endif
- if (&x != this){
- this->swap(x);
- x.clear();
- }
- return *this;
- }
-
- //! <b>Effects</b>: Assigns the n copies of val to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- void assign(size_type n, const value_type& val)
- { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
-
- //! <b>Effects</b>: Assigns the the range [first, last) to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's constructor from dereferencing InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- template <class InIt>
- void assign(InIt first, InIt last)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
- }
-
- //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_back(const T& x)
- {
- if (this->members_.m_size < this->members_.m_capacity){
- //There is more memory, just construct a new object at the end
- new((void*)(detail::get_pointer(this->members_.m_start) + this->members_.m_size))value_type(x);
- ++this->members_.m_size;
- }
- else{
- this->insert(this->cend(), x);
- }
- }
-
- //! <b>Effects</b>: Constructs a new element in the end of the vector
- //! and moves the resources of mx to this new element.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void push_back(detail::moved_object<T> mx)
- {
- value_type &x = mx.get();
- #else
- void push_back(T && x)
- {
- #endif
- if (this->members_.m_size < this->members_.m_capacity){
- //There is more memory, just construct a new object at the end
- new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(detail::move_impl(x));
- ++this->members_.m_size;
- }
- else{
- this->insert(this->cend(), detail::move_impl(x));
- }
- }
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the end of the vector.
- //!
- //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- template<class ...Args>
- void emplace_back(Args &&...args)
- {
- T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
- if (this->members_.m_size < this->members_.m_capacity){
- //There is more memory, just construct a new object at the end
- new((void*)(back_pos))value_type(detail::forward_impl<Args>(args)...);
- ++this->members_.m_size;
- }
- else{
- detail::advanced_insert_aux_emplace<T, T*, Args...> proxy
- (detail::forward_impl<Args>(args)...);
- priv_range_insert(back_pos, 1, proxy);
- }
- }
-
- //! <b>Requires</b>: position must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... before position
- //!
- //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
- //!
- //! <b>Complexity</b>: If position is end(), amortized constant time
- //! Linear time otherwise.
- template<class ...Args>
- iterator emplace(const_iterator position, Args && ...args)
- {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- detail::advanced_insert_aux_emplace<T, T*, Args...> proxy
- (detail::forward_impl<Args>(args)...);
- priv_range_insert(position.get_ptr(), 1, proxy);
- return iterator(this->members_.m_start + pos_n);
- }
-
- #else
-
- void emplace_back()
- {
- T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
- if (this->members_.m_size < this->members_.m_capacity){
- //There is more memory, just construct a new object at the end
- new((void*)(back_pos))value_type();
- ++this->members_.m_size;
- }
- else{
- detail::advanced_insert_aux_emplace<value_type, T*> proxy;
- priv_range_insert(back_pos, 1, proxy);
- }
- }
-
- iterator emplace(const_iterator position)
- {
- size_type pos_n = position - cbegin();
- detail::advanced_insert_aux_emplace<value_type, T*> proxy;
- priv_range_insert(detail::get_pointer(position.get_ptr()), 1, proxy);
- return iterator(this->members_.m_start + pos_n);
- }
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size; \
- if (this->members_.m_size < this->members_.m_capacity){ \
- new((void*)(back_pos))value_type \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- ++this->members_.m_size; \
- } \
- else{ \
- detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
- proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- priv_range_insert(back_pos, 1, proxy); \
- } \
- } \
- \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- { \
- size_type pos_n = pos - cbegin(); \
- detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
- proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
- priv_range_insert(detail::get_pointer(pos.get_ptr()), 1, proxy); \
- return iterator(this->members_.m_start + pos_n); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type()
- //! allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<vector> x)
- { this->swap(x.get()); }
- void swap(vector& x)
- #else
- void swap(vector &&x)
- #endif
- {
- allocator_type &this_al = this->alloc(), &other_al = x.alloc();
- //Just swap internals
- detail::do_swap(this->members_.m_start, x.members_.m_start);
- detail::do_swap(this->members_.m_size, x.members_.m_size);
- detail::do_swap(this->members_.m_capacity, x.members_.m_capacity);
-
- if (this_al != other_al){
- detail::do_swap(this_al, other_al);
- }
- }
-
- //! <b>Requires</b>: position must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of x before position.
- //!
- //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
- //!
- //! <b>Complexity</b>: If position is end(), amortized constant time
- //! Linear time otherwise.
- iterator insert(const_iterator position, const T& x)
- {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position, (size_type)1, x);
- return iterator(this->members_.m_start + pos_n);
- }
-
- //! <b>Requires</b>: position must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a new element before position with mx's resources.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: If position is end(), amortized constant time
- //! Linear time otherwise.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, detail::moved_object<T> mx)
- {
- value_type &x = mx.get();
- #else
- iterator insert(const_iterator position, T &&x)
- {
- #endif
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position
- ,repeat_move_it(repeat_it(x, 1))
- ,repeat_move_it(repeat_it()));
- return iterator(this->members_.m_start + pos_n);
- }
-
- //! <b>Requires</b>: pos must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
- //!
- //! <b>Throws</b>: If memory allocation throws, T's constructor from a
- //! dereferenced InpIt throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
- template <class InIt>
- void insert(const_iterator pos, InIt first, InIt last)
- {
- //Dispatch depending on integer/iterator
- const bool aux_boolean = detail::is_convertible<InIt, std::size_t>::value;
- typedef detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(pos, first, last, Result());
- }
-
- //! <b>Requires</b>: pos must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert n copies of x before pos.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- void insert(const_iterator p, size_type n, const T& x)
- { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
-
- //! <b>Effects</b>: Removes the last element from the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant time.
- void pop_back()
- {
- //Destroy last element
- --this->members_.m_size;
- this->destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size);
- }
-
- //! <b>Effects</b>: Erases the element at position pos.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the elements between pos and the
- //! last element. Constant if pos is the first or the last element.
- iterator erase(const_iterator position)
- {
- T *pos = detail::get_pointer(position.get_ptr());
- T *beg = detail::get_pointer(this->members_.m_start);
- typedef typename value_traits::assign_move_it assign_move_it;
- std::copy(assign_move_it(pos + 1), assign_move_it(beg + this->members_.m_size), pos);
- --this->members_.m_size;
- //Destroy last element
- base_t::destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size);
- return iterator(position.get_ptr());
- }
-
- //! <b>Effects</b>: Erases the elements pointed by [first, last).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the distance between first and last.
- iterator erase(const_iterator first, const_iterator last)
- {
- typedef typename value_traits::assign_move_it assign_move_it;
- if (first != last){ // worth doing, copy down over hole
- T* end_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
- T* ptr = detail::get_pointer(std::copy
- (assign_move_it(detail::get_pointer(last.get_ptr()))
- ,assign_move_it(end_pos)
- ,detail::get_pointer(first.get_ptr())
- ));
- size_type destroyed = (end_pos - ptr);
- this->destroy_n(ptr, destroyed);
- this->members_.m_size -= destroyed;
- }
- return iterator(first.get_ptr());
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size, const T& x)
- {
- pointer finish = this->members_.m_start + this->members_.m_size;
- if (new_size < size()){
- //Destroy last elements
- this->erase(const_iterator(this->members_.m_start + new_size), this->end());
- }
- else{
- //Insert new elements at the end
- this->insert(const_iterator(finish), new_size - this->size(), x);
- }
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size)
- {
- if (new_size < this->size()){
- //Destroy last elements
- this->erase(const_iterator(this->members_.m_start + new_size), this->end());
- }
- else{
- size_type n = new_size - this->size();
- this->reserve(new_size);
- detail::default_construct_aux_proxy<T, T*, size_type> proxy(n);
- priv_range_insert(this->cend().get_ptr(), n, proxy);
- }
- }
-
- //! <b>Effects</b>: Erases all the elements of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the vector.
- void clear()
- { this->prot_destroy_all(); }
-
- /// @cond
-
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- //! with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { priv_shrink_to_fit(alloc_version()); }
-
- private:
- void priv_shrink_to_fit(allocator_v1)
- {
- if(this->members_.m_capacity){
- if(!size()){
- this->prot_deallocate();
- }
- else{
- //This would not work with stateful allocators
- vector<T, A>(*this).swap(*this);
- }
- }
- }
-
- void priv_shrink_to_fit(allocator_v2)
- {
- if(this->members_.m_capacity){
- if(!size()){
- this->prot_deallocate();
- }
- else{
- size_type received_size;
- if(this->alloc().allocation_command
- ( shrink_in_place | nothrow_allocation
- , this->capacity(), this->size()
- , received_size, this->members_.m_start).first){
- this->members_.m_capacity = received_size;
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_shrink;
- #endif
- }
- }
- }
- }
-
- template <class FwdIt>
- void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- if(first != last){
- const size_type n = std::distance(first, last);
- detail::advanced_insert_aux_proxy<T, FwdIt, T*> proxy(first, last);
- priv_range_insert(pos, n, proxy);
- }
- }
-
- void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
- {
- //Check if we have enough memory or try to expand current memory
- size_type remaining = this->members_.m_capacity - this->members_.m_size;
- bool same_buffer_start;
- std::pair<pointer, bool> ret;
- size_type real_cap = this->members_.m_capacity;
-
- //Check if we already have room
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new
- //buffer or expand the old one.
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
-
- //Check for forward expansion
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
- }
- }
-
- //If we had room or we have expanded forward
- if (same_buffer_start){
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_expand_fwd;
- #endif
- this->priv_range_insert_expand_forward
- (detail::get_pointer(pos), n, interf);
- }
- //Backwards (and possibly forward) expansion
- else if(ret.second){
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_expand_bwd;
- #endif
- this->priv_range_insert_expand_backwards
- ( detail::get_pointer(ret.first)
- , real_cap
- , detail::get_pointer(pos)
- , n
- , interf);
- }
- //New buffer
- else{
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- ++this->num_alloc;
- #endif
- this->priv_range_insert_new_allocation
- ( detail::get_pointer(ret.first)
- , real_cap
- , detail::get_pointer(pos)
- , n
- , interf);
- }
- }
-
- void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
- {
- typedef typename value_traits::copy_move_it copy_move_it;
- typedef typename value_traits::assign_move_it assign_move_it;
- //There is enough memory
- T* old_finish = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
- const size_type elems_after = old_finish - pos;
-
- if (elems_after > n){
- //New elements can be just copied.
- //Move to uninitialized memory last objects
- std::uninitialized_copy(copy_move_it(old_finish - n), copy_move_it(old_finish), old_finish);
- this->members_.m_size += n;
- //Copy previous to last objects to the initialized end
- std::copy_backward(assign_move_it(pos), assign_move_it(old_finish - n), old_finish);
- //Insert new objects in the pos
- interf.copy_all_to(pos);
- }
- else {
- //The new elements don't fit in the [pos, end()) range. Copy
- //to the beginning of the unallocated zone the last new elements.
- interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
- this->members_.m_size += n - elems_after;
- //Copy old [pos, end()) elements to the uninitialized memory
- std::uninitialized_copy
- ( copy_move_it(pos), copy_move_it(old_finish)
- , detail::get_pointer(this->members_.m_start) + this->members_.m_size);
- this->members_.m_size += elems_after;
- //Copy first new elements in pos
- interf.copy_all_to(pos);
- }
- }
-
- void priv_range_insert_new_allocation
- (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
- {
- typedef typename value_traits::copy_move_it copy_move_it;
- T* new_finish = new_start;
- T *old_finish;
- //Anti-exception rollbacks
- typename value_traits::UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
- typename value_traits::UCopiedArrayDestructor constructed_values_destroyer(new_start, 0u);
-
- //Initialize with [begin(), pos) old buffer
- //the start of the new buffer
- new_finish = std::uninitialized_copy
- ( copy_move_it(detail::get_pointer(this->members_.m_start))
- , copy_move_it(pos)
- , old_finish = new_finish);
- constructed_values_destroyer.increment_size(new_finish - old_finish);
- //Initialize new objects, starting from previous point
- interf.uninitialized_copy_all_to(old_finish = new_finish);
- new_finish += n;
- constructed_values_destroyer.increment_size(new_finish - old_finish);
- //Initialize from the rest of the old buffer,
- //starting from previous point
- new_finish = std::uninitialized_copy
- ( copy_move_it(pos)
- , copy_move_it(detail::get_pointer(this->members_.m_start) + this->members_.m_size)
- , new_finish);
-
- //All construction successful, disable rollbacks
- constructed_values_destroyer.release();
- scoped_alloc.release();
- //Destroy and deallocate old elements
- //If there is allocated memory, destroy and deallocate
- if(this->members_.m_start != 0){
- if(!value_traits::trivial_dctr_after_move)
- this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
- this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
- }
- this->members_.m_start = new_start;
- this->members_.m_size = new_finish - new_start;
- this->members_.m_capacity = new_cap;
- }
-
- void priv_range_insert_expand_backwards
- (T* new_start, size_type new_capacity,
- T* pos, const size_type n, advanced_insert_aux_int_t &interf)
- {
- typedef typename value_traits::copy_move_it copy_move_it;
- typedef typename value_traits::assign_move_it assign_move_it;
-
- //Backup old data
- T* old_start = detail::get_pointer(this->members_.m_start);
- T* old_finish = old_start + this->members_.m_size;
- size_type old_size = this->members_.m_size;
-
- //We can have 8 possibilities:
- const size_type elemsbefore = (size_type)(pos - old_start);
- const size_type s_before = (size_type)(old_start - new_start);
-
- //Update the vector buffer information to a safe state
- this->members_.m_start = new_start;
- this->members_.m_capacity = new_capacity;
- this->members_.m_size = 0;
-
- //If anything goes wrong, this object will destroy
- //all the old objects to fulfill previous vector state
- typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
- //Check if s_before is big enough to hold the beginning of old data + new data
- if(difference_type(s_before) >= difference_type(elemsbefore + n)){
- //Copy first old values before pos, after that the new objects
- std::uninitialized_copy(copy_move_it(old_start), copy_move_it(pos), new_start);
- this->members_.m_size = elemsbefore;
- interf.uninitialized_copy_all_to(new_start + elemsbefore);
- this->members_.m_size += n;
- //Check if s_before is so big that even copying the old data + new data
- //there is a gap between the new data and the old data
- if(s_before >= (old_size + n)){
- //Old situation:
- // _________________________________________________________
- //| raw_mem | old_begin | old_end |
- //| __________________________________|___________|_________|
- //
- //New situation:
- // _________________________________________________________
- //| old_begin | new | old_end | raw_mem |
- //|___________|__________|_________|________________________|
- //
- //Now initialize the rest of memory with the last old values
- std::uninitialized_copy
- (copy_move_it(pos), copy_move_it(old_finish), new_start + elemsbefore + n);
- //All new elements correctly constructed, avoid new element destruction
- this->members_.m_size = old_size + n;
- //Old values destroyed automatically with "old_values_destroyer"
- //when "old_values_destroyer" goes out of scope unless the have trivial
- //destructor after move.
- if(value_traits::trivial_dctr_after_move)
- old_values_destroyer.release();
- }
- //s_before is so big that divides old_end
- else{
- //Old situation:
- // __________________________________________________
- //| raw_mem | old_begin | old_end |
- //| ___________________________|___________|_________|
- //
- //New situation:
- // __________________________________________________
- //| old_begin | new | old_end | raw_mem |
- //|___________|__________|_________|_________________|
- //
- //Now initialize the rest of memory with the last old values
- //All new elements correctly constructed, avoid new element destruction
- size_type raw_gap = s_before - (elemsbefore + n);
- //Now initialize the rest of s_before memory with the
- //first of elements after new values
- std::uninitialized_copy
- (copy_move_it(pos), copy_move_it(pos + raw_gap), new_start + elemsbefore + n);
- //Update size since we have a contiguous buffer
- this->members_.m_size = old_size + s_before;
- //All new elements correctly constructed, avoid old element destruction
- old_values_destroyer.release();
- //Now copy remaining last objects in the old buffer begin
- T *to_destroy = std::copy(assign_move_it(pos + raw_gap), assign_move_it(old_finish), old_start);
- //Now destroy redundant elements except if they were moved and
- //they have trivial destructor after move
- size_type n_destroy = old_finish - to_destroy;
- if(!value_traits::trivial_dctr_after_move)
- this->destroy_n(to_destroy, n_destroy);
- this->members_.m_size -= n_destroy;
- }
- }
- else{
- //Check if we have to do the insertion in two phases
- //since maybe s_before is not big enough and
- //the buffer was expanded both sides
- //
- //Old situation:
- // _________________________________________________
- //| raw_mem | old_begin + old_end | raw_mem |
- //|_________|_____________________|_________________|
- //
- //New situation with do_after:
- // _________________________________________________
- //| old_begin + new + old_end | raw_mem |
- //|___________________________________|_____________|
- //
- //New without do_after:
- // _________________________________________________
- //| old_begin + new + old_end | raw_mem |
- //|____________________________|____________________|
- //
- bool do_after = n > s_before;
-
- //Now we can have two situations: the raw_mem of the
- //beginning divides the old_begin, or the new elements:
- if (s_before <= elemsbefore) {
- //The raw memory divides the old_begin group:
- //
- //If we need two phase construction (do_after)
- //new group is divided in new = new_beg + new_end groups
- //In this phase only new_beg will be inserted
- //
- //Old situation:
- // _________________________________________________
- //| raw_mem | old_begin | old_end | raw_mem |
- //|_________|___________|_________|_________________|
- //
- //New situation with do_after(1):
- //This is not definitive situation, the second phase
- //will include
- // _________________________________________________
- //| old_begin | new_beg | old_end | raw_mem |
- //|___________|_________|_________|_________________|
- //
- //New situation without do_after:
- // _________________________________________________
- //| old_begin | new | old_end | raw_mem |
- //|___________|_____|_________|_____________________|
- //
- //Copy the first part of old_begin to raw_mem
- T *start_n = old_start + difference_type(s_before);
- std::uninitialized_copy(copy_move_it(old_start), copy_move_it(start_n), new_start);
- //The buffer is all constructed until old_end,
- //release destroyer and update size
- old_values_destroyer.release();
- this->members_.m_size = old_size + s_before;
- //Now copy the second part of old_begin overwriting himself
- T* next = std::copy(assign_move_it(start_n), assign_move_it(pos), old_start);
- if(do_after){
- //Now copy the new_beg elements
- interf.copy_some_and_update(next, s_before, true);
- }
- else{
- //Now copy the all the new elements
- interf.copy_all_to(next);
- T* move_start = next + n;
- //Now displace old_end elements
- T* move_end = std::copy(assign_move_it(pos), assign_move_it(old_finish), move_start);
- //Destroy remaining moved elements from old_end except if
- //they have trivial destructor after being moved
- difference_type n_destroy = s_before - n;
- if(!value_traits::trivial_dctr_after_move)
- this->destroy_n(move_end, n_destroy);
- this->members_.m_size -= n_destroy;
- }
- }
- else {
- //If we have to expand both sides,
- //we will play if the first new values so
- //calculate the upper bound of new values
-
- //The raw memory divides the new elements
- //
- //If we need two phase construction (do_after)
- //new group is divided in new = new_beg + new_end groups
- //In this phase only new_beg will be inserted
- //
- //Old situation:
- // _______________________________________________________
- //| raw_mem | old_begin | old_end | raw_mem |
- //|_______________|___________|_________|_________________|
- //
- //New situation with do_after():
- // ____________________________________________________
- //| old_begin | new_beg | old_end | raw_mem |
- //|___________|_______________|_________|______________|
- //
- //New situation without do_after:
- // ______________________________________________________
- //| old_begin | new | old_end | raw_mem |
- //|___________|_____|_________|__________________________|
- //
- //First copy whole old_begin and part of new to raw_mem
- std::uninitialized_copy(copy_move_it(old_start), copy_move_it(pos), new_start);
- this->members_.m_size = elemsbefore;
-
- const size_type mid_n = difference_type(s_before) - elemsbefore;
- interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
- this->members_.m_size = old_size + s_before;
- //The buffer is all constructed until old_end,
- //release destroyer and update size
- old_values_destroyer.release();
-
- if(do_after){
- //Copy new_beg part
- interf.copy_some_and_update(old_start, s_before - mid_n, true);
- }
- else{
- //Copy all new elements
- interf.copy_all_to(old_start);
- T* move_start = old_start + (n-mid_n);
- //Displace old_end
- T* move_end = std::copy(copy_move_it(pos), copy_move_it(old_finish), move_start);
- //Destroy remaining moved elements from old_end except if they
- //have trivial destructor after being moved
- difference_type n_destroy = s_before - n;
- if(!value_traits::trivial_dctr_after_move)
- this->destroy_n(move_end, n_destroy);
- this->members_.m_size -= n_destroy;
- }
- }
-
- //This is only executed if two phase construction is needed
- //This can be executed without exception handling since we
- //have to just copy and append in raw memory and
- //old_values_destroyer has been released in phase 1.
- if(do_after){
- //The raw memory divides the new elements
- //
- //Old situation:
- // ______________________________________________________
- //| raw_mem | old_begin | old_end | raw_mem |
- //|______________|___________|____________|______________|
- //
- //New situation with do_after(1):
- // _______________________________________________________
- //| old_begin + new_beg | new_end |old_end | raw_mem |
- //|__________________________|_________|________|_________|
- //
- //New situation with do_after(2):
- // ______________________________________________________
- //| old_begin + new | old_end |raw |
- //|_______________________________________|_________|____|
- //
- const size_type n_after = n - s_before;
- const difference_type elemsafter = old_size - elemsbefore;
-
- //We can have two situations:
- if (elemsafter > difference_type(n_after)){
- //The raw_mem from end will divide displaced old_end
- //
- //Old situation:
- // ______________________________________________________
- //| raw_mem | old_begin | old_end | raw_mem |
- //|______________|___________|____________|______________|
- //
- //New situation with do_after(1):
- // _______________________________________________________
- //| old_begin + new_beg | new_end |old_end | raw_mem |
- //|__________________________|_________|________|_________|
- //
- //First copy the part of old_end raw_mem
- T* finish_n = old_finish - difference_type(n_after);
- std::uninitialized_copy
- (copy_move_it(finish_n), copy_move_it(old_finish), old_finish);
- this->members_.m_size += n_after;
- //Displace the rest of old_end to the new position
- std::copy_backward(assign_move_it(pos), assign_move_it(finish_n), old_finish);
- //Now overwrite with new_end
- //The new_end part is [first + (n - n_after), last)
- interf.copy_all_to(pos);
- }
- else {
- //The raw_mem from end will divide new_end part
- //
- //Old situation:
- // _____________________________________________________________
- //| raw_mem | old_begin | old_end | raw_mem |
- //|______________|___________|____________|_____________________|
- //
- //New situation with do_after(2):
- // _____________________________________________________________
- //| old_begin + new_beg | new_end |old_end | raw_mem |
- //|__________________________|_______________|________|_________|
- //
- size_type mid_last_dist = n_after - elemsafter;
- //First initialize data in raw memory
- //The new_end part is [first + (n - n_after), last)
- interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
- this->members_.m_size += mid_last_dist;
- std::uninitialized_copy(copy_move_it(pos), copy_move_it(old_finish), old_finish + mid_last_dist);
- this->members_.m_size += n_after - mid_last_dist;
- //Now copy the part of new_end over constructed elements
- interf.copy_all_to(pos);
- }
- }
- }
- }
-
- template <class InIt>
- void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag)
- {
- for(;first != last; ++first){
- this->insert(pos, detail::move_impl(value_type(*first)));
- }
- }
-
- template <class InIt>
- void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag)
- {
- //Overwrite all elements we can from [first, last)
- iterator cur = begin();
- for ( ; first != last && cur != end(); ++cur, ++first){
- *cur = *first;
- }
-
- if (first == last){
- //There are no more elements in the sequence, erase remaining
- this->erase(cur, cend());
- }
- else{
- //There are more elements in the range, insert the remaining ones
- this->insert(this->cend(), first, last);
- }
- }
-
- template <class FwdIt>
- void priv_assign_aux(FwdIt first, FwdIt last,
- std::forward_iterator_tag)
- {
- size_type n = std::distance(first, last);
- //Check if we have enough memory or try to expand current memory
- size_type remaining = this->members_.m_capacity - this->members_.m_size;
- bool same_buffer_start;
- std::pair<pointer, bool> ret;
- size_type real_cap = this->members_.m_capacity;
-
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new buffer
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->size() + n, new_cap, real_cap, this->members_.m_start);
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
- }
- }
-
- if(same_buffer_start){
- T *start = detail::get_pointer(this->members_.m_start);
- if (this->size() >= n){
- //There is memory, but there are more old elements than new ones
- //Overwrite old elements with new ones
- std::copy(first, last, start);
- //Destroy remaining old elements
- this->destroy_n(start + n, this->members_.m_size - n);
- this->members_.m_size = n;
- }
- else{
- //There is memory, but there are less old elements than new ones
- //First overwrite some old elements with new ones
- FwdIt mid = first;
- std::advance(mid, this->size());
- T *end = std::copy(first, mid, start);
- //Initialize the remaining new elements in the uninitialized memory
- std::uninitialized_copy(mid, last, end);
- this->members_.m_size = n;
- }
- }
- else if(!ret.second){
- typename value_traits::UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
- std::uninitialized_copy(first, last, detail::get_pointer(ret.first));
- scoped_alloc.release();
- //Destroy and deallocate old buffer
- if(this->members_.m_start != 0){
- this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
- this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
- }
- this->members_.m_start = ret.first;
- this->members_.m_size = n;
- this->members_.m_capacity = real_cap;
- }
- else{
- //Backwards expansion
- //If anything goes wrong, this object will destroy old objects
- T *old_start = detail::get_pointer(this->members_.m_start);
- size_type old_size = this->members_.m_size;
- typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
- //If something goes wrong size will be 0
- //but holding the whole buffer
- this->members_.m_size = 0;
- this->members_.m_start = ret.first;
- this->members_.m_capacity = real_cap;
-
- //Backup old buffer data
- size_type old_offset = old_start - detail::get_pointer(ret.first);
- size_type first_count = min_value(n, old_offset);
-
- FwdIt mid = first;
- std::advance(mid, first_count);
- std::uninitialized_copy(first, mid, detail::get_pointer(ret.first));
-
- if(old_offset > n){
- //All old elements will be destroyed by "old_values_destroyer"
- this->members_.m_size = n;
- }
- else{
- //We have constructed objects from the new begin until
- //the old end so release the rollback destruction
- old_values_destroyer.release();
- this->members_.m_start = ret.first;
- this->members_.m_size = first_count + old_size;
- //Now overwrite the old values
- size_type second_count = min_value(old_size, n - first_count);
- FwdIt mid2 = mid;
- std::advance(mid2, second_count);
- std::copy(mid, mid2, old_start);
-
- //Check if we still have to append elements in the
- //uninitialized end
- if(second_count == old_size){
- std::copy(mid2, last, old_start + old_size);
- }
- else{
- //We have to destroy some old values
- this->destroy_n
- (old_start + second_count, old_size - second_count);
- this->members_.m_size = n;
- }
- this->members_.m_size = n;
- }
- }
- }
-
- template <class Integer>
- void priv_assign_dispatch(Integer n, Integer val, detail::true_)
- { this->assign((size_type) n, (T) val); }
-
- template <class InIt>
- void priv_assign_dispatch(InIt first, InIt last, detail::false_)
- {
- //Dispatch depending on integer/iterator
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_assign_aux(first, last, ItCat());
- }
-
- template <class Integer>
- void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, detail::true_)
- { this->insert(pos, (size_type)n, (T)val); }
-
- template <class InIt>
- void priv_insert_dispatch(const_iterator pos, InIt first,
- InIt last, detail::false_)
- {
- //Dispatch depending on integer/iterator
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_range_insert(pos.get_ptr(), first, last, ItCat());
- }
-
- void priv_check_range(size_type n) const
- {
- //If n is out of range, throw an out_of_range exception
- if (n >= size())
- throw std::out_of_range("vector::at");
- }
-
- #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
- public:
- unsigned int num_expand_fwd;
- unsigned int num_expand_bwd;
- unsigned int num_shrink;
- unsigned int num_alloc;
- void reset_alloc_stats()
- { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
- #endif
- /// @endcond
-};
-
-template <class T, class A>
-inline bool
-operator==(const vector<T, A>& x, const vector<T, A>& y)
-{
- //Check first size and each element if needed
- return x.size() == y.size() &&
- std::equal(x.begin(), x.end(), y.begin());
-}
-
-template <class T, class A>
-inline bool
-operator!=(const vector<T, A>& x, const vector<T, A>& y)
-{
- //Check first size and each element if needed
- return x.size() != y.size() ||
- !std::equal(x.begin(), x.end(), y.begin());
-}
-
-template <class T, class A>
-inline bool
-operator<(const vector<T, A>& x, const vector<T, A>& y)
-{
- return std::lexicographical_compare(x.begin(), x.end(),
- y.begin(), y.end());
-}
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
-template <class T, class A>
-inline void swap(vector<T, A>& x, vector<T, A>& y)
-{ x.swap(y); }
-
-template <class T, class A>
-inline void swap(detail::moved_object<vector<T, A> > x, vector<T, A>& y)
-{ x.get().swap(y); }
-
-template <class T, class A>
-inline void swap(vector<T, A> &x, detail::moved_object<vector<T, A> > y)
-{ x.swap(y.get()); }
-#else
-template <class T, class A>
-inline void swap(vector<T, A>&&x, vector<T, A>&&y)
-{ x.swap(y); }
-#endif
-
-/// @cond
-
-//!This class is movable
-template <class T, class A>
-struct is_movable<vector<T, A> >
-{
- enum { value = true };
-};
-
-//!has_trivial_destructor_after_move<> == true_type
-//!specialization for optimizations
-template <class T, class A>
-struct has_trivial_destructor_after_move<vector<T, A> >
-{
- enum { value = has_trivial_destructor<A>::value };
-};
-/// @endcond
+using boost::interprocess_container::vector;
} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
-#endif // #ifndef BOOST_INTERPROCESS_VECTOR_HPP
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_VECTOR_HPP
Added: trunk/boost/interprocess/containers/version_type.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/version_type.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,33 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/version_type.hpp>
+
+namespace boost {
+namespace interprocess {
+
+using boost::interprocess_container::containers_detail::version_type;
+using boost::interprocess_container::containers_detail::version;
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
+
Deleted: trunk/boost/interprocess/detail/advanced_insert_int.hpp
==============================================================================
--- trunk/boost/interprocess/detail/advanced_insert_int.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,395 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_ADVANCED_INSERT_INT_HPP
-#define BOOST_INTERPROCESS_ADVANCED_INSERT_INT_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <iterator> //std::iterator_traits
-#include <algorithm> //std::copy, std::uninitialized_copy
-#include <new> //placement new
-#include <cassert>
-
-namespace boost { namespace interprocess { namespace detail {
-
-//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
-template<class T, class Iterator>
-struct advanced_insert_aux_int
-{
- typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
- virtual void copy_all_to(Iterator p) = 0;
- virtual void uninitialized_copy_all_to(Iterator p) = 0;
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
- virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
- virtual ~advanced_insert_aux_int() {}
-};
-
-//This class template will adapt each FwIt types to advanced_insert_aux_int
-template<class T, class FwdIt, class Iterator>
-struct advanced_insert_aux_proxy
- : public advanced_insert_aux_int<T, Iterator>
-{
- typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
- advanced_insert_aux_proxy(FwdIt first, FwdIt last)
- : first_(first), last_(last)
- {}
-
- virtual ~advanced_insert_aux_proxy()
- {}
-
- virtual void copy_all_to(Iterator p)
- { *std::copy(first_, last_, p); }
-
- virtual void uninitialized_copy_all_to(Iterator p)
- { std::uninitialized_copy(first_, last_, p); }
-
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
- {
- FwdIt mid = first_;
- std::advance(mid, division_count);
- if(first_n){
- std::uninitialized_copy(first_, mid, pos);
- first_ = mid;
- }
- else{
- std::uninitialized_copy(mid, last_, pos);
- last_ = mid;
- }
- }
-
- virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
- {
- FwdIt mid = first_;
- std::advance(mid, division_count);
- if(first_n){
- std::copy(first_, mid, pos);
- first_ = mid;
- }
- else{
- std::copy(mid, last_, pos);
- last_ = mid;
- }
- }
-
- FwdIt first_, last_;
-};
-
-//This class template will adapt each FwIt types to advanced_insert_aux_int
-template<class T, class Iterator, class SizeType>
-struct default_construct_aux_proxy
- : public advanced_insert_aux_int<T, Iterator>
-{
- typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
- default_construct_aux_proxy(SizeType count)
- : count_(count)
- {}
-
- void uninitialized_copy_impl(Iterator p, const SizeType n)
- {
- assert(n <= count_);
- Iterator orig_p = p;
- SizeType i = 0;
- try{
- for(; i < n; ++i, ++p){
- new(detail::get_pointer(&*p))T();
- }
- }
- catch(...){
- while(i--){
- detail::get_pointer(&*orig_p++)->~T();
- }
- throw;
- }
- count_ -= n;
- }
-
- virtual ~default_construct_aux_proxy()
- {}
-
- virtual void copy_all_to(Iterator)
- { //This should never be called with any count
- assert(count_ == 0);
- }
-
- virtual void uninitialized_copy_all_to(Iterator p)
- { this->uninitialized_copy_impl(p, count_); }
-
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
- {
- SizeType new_count;
- if(first_n){
- new_count = division_count;
- }
- else{
- assert(difference_type(count_)>= division_count);
- new_count = count_ - division_count;
- }
- this->uninitialized_copy_impl(pos, new_count);
- }
-
- virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
- {
- assert(count_ == 0);
- SizeType new_count;
- if(first_n){
- new_count = division_count;
- }
- else{
- assert(difference_type(count_)>= division_count);
- new_count = count_ - division_count;
- }
- //This function should never called with a count different to zero
- assert(new_count == 0);
- (void)new_count;
- }
-
- SizeType count_;
-};
-
-}}} //namespace boost { namespace interprocess { namespace detail {
-
-#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
-#include <boost/interprocess/detail/variadic_templates_tools.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include <typeinfo>
-//#include <iostream> //For debugging purposes
-
-namespace boost {
-namespace interprocess {
-namespace detail {
-
-//This class template will adapt each FwIt types to advanced_insert_aux_int
-template<class T, class Iterator, class ...Args>
-struct advanced_insert_aux_emplace
- : public advanced_insert_aux_int<T, Iterator>
-{
- typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
- typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
-
- advanced_insert_aux_emplace(Args&&... args)
- : args_(args...), used_(false)
- {}
-
- ~advanced_insert_aux_emplace()
- {}
-
- virtual void copy_all_to(Iterator p)
- { this->priv_copy_all_to(index_tuple_t(), p); }
-
- virtual void uninitialized_copy_all_to(Iterator p)
- { this->priv_uninitialized_copy_all_to(index_tuple_t(), p); }
-
- virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
-
- virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- { this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
-
- private:
- template<int ...IdxPack>
- void priv_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
- {
- if(!used_){
- T object(detail::forward_impl<Args>(get<IdxPack>(args_))...);
- *p = detail::move_impl(object);
- used_ = true;
- }
- }
-
- template<int ...IdxPack>
- void priv_uninitialized_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
- {
- if(!used_){
- new(detail::get_pointer(&*p))T(detail::forward_impl<Args>(get<IdxPack>(args_))...);
- used_ = true;
- }
- }
-
- template<int ...IdxPack>
- void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
- {
- assert(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!used_){
- new(detail::get_pointer(&*p))T(detail::forward_impl<Args>(get<IdxPack>(args_))...);
- used_ = true;
- }
- }
- }
-
- template<int ...IdxPack>
- void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
- {
- assert(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!used_){
- T object(detail::forward_impl<Args>(get<IdxPack>(args_))...);
- *p = detail::move_impl(object);
- used_ = true;
- }
- }
- }
- tuple<Args&&...> args_;
- bool used_;
-};
-
-}}} //namespace boost { namespace interprocess { namespace detail {
-
-#else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
-#include <boost/interprocess/detail/preprocessor.hpp>
-
-namespace boost {
-namespace interprocess {
-namespace detail {
-
-template<class T>
-struct value_init_helper
-{
- value_init_helper()
- : m_t()
- {}
-
- T m_t;
-};
-
-//This class template will adapt each FwIt types to advanced_insert_aux_int
-template<class T, class Iterator>
-struct advanced_insert_aux_emplace
- : public advanced_insert_aux_int<T, Iterator>
-{
- typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
- advanced_insert_aux_emplace()
- : used_(false)
- {}
-
- ~advanced_insert_aux_emplace()
- {}
-
- virtual void copy_all_to(Iterator p)
- {
- if(!used_){
- value_init_helper<T>v;
- *p = detail::move_impl(v.m_t);
- used_ = true;
- }
- }
-
- virtual void uninitialized_copy_all_to(Iterator p)
- {
- if(!used_){
- new(detail::get_pointer(&*p))T();
- used_ = true;
- }
- }
-
- virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- {
- assert(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!used_){
- new(detail::get_pointer(&*p))T();
- used_ = true;
- }
- }
- }
-
- virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- {
- assert(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!used_){
- value_init_helper<T>v;
- *p = detail::move_impl(v.m_t);
- used_ = true;
- }
- }
- }
- private:
- bool used_;
-};
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<class T, class Iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
- struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- : public advanced_insert_aux_int<T, Iterator> \
- { \
- typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type; \
- \
- BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _) ) \
- : used_(false), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \
- \
- virtual void copy_all_to(Iterator p) \
- { \
- if(!used_){ \
- T v(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
- *p = detail::move_impl(v); \
- used_ = true; \
- } \
- } \
- \
- virtual void uninitialized_copy_all_to(Iterator p) \
- { \
- if(!used_){ \
- new(detail::get_pointer(&*p))T \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
- used_ = true; \
- } \
- } \
- \
- virtual void uninitialized_copy_some_and_update \
- (Iterator p, difference_type division_count, bool first_n) \
- { \
- assert(division_count <=1); \
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!used_){ \
- new(detail::get_pointer(&*p))T \
- (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
- used_ = true; \
- } \
- } \
- } \
- \
- virtual void copy_some_and_update \
- (Iterator p, difference_type division_count, bool first_n) \
- { \
- assert(division_count <=1); \
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!used_){ \
- T v(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
- *p = detail::move_impl(v); \
- used_ = true; \
- } \
- } \
- } \
- \
- bool used_; \
- BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
- }; \
-//!
-
-#define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
-#include BOOST_PP_LOCAL_ITERATE()
-
-}}} //namespace boost { namespace interprocess { namespace detail {
-
-#endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_ADVANCED_INSERT_INT_HPP
Deleted: trunk/boost/interprocess/detail/algorithms.hpp
==============================================================================
--- trunk/boost/interprocess/detail/algorithms.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,205 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008.
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP
-#define BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
-#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/detail/no_exceptions_support.hpp>
-#include <boost/get_pointer.hpp>
-#include <cstring>
-
-namespace boost {
-namespace interprocess {
-
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) || !defined(BOOST_INTERPROCESS_RVALUE_PAIR)
-
-template<class T>
-struct has_own_construct_from_it
-{
- static const bool value = false;
-};
-
-namespace detail {
-
-template<class T, class InpIt>
-inline void construct_in_place_impl(T* dest, const InpIt &source, detail::true_)
-{
- T::construct(dest, *source);
-}
-
-template<class T, class InpIt>
-inline void construct_in_place_impl(T* dest, const InpIt &source, detail::false_)
-{
- new((void*)dest)T(*source);
-}
-
-} //namespace detail {
-
-template<class T, class InpIt>
-inline void construct_in_place(T* dest, InpIt source)
-{
- typedef detail::bool_<has_own_construct_from_it<T>::value> boolean_t;
- detail::construct_in_place_impl(dest, source, boolean_t());
-}
-
-#else
-template<class T, class InpIt>
-inline void construct_in_place(T* dest, InpIt source)
-{ new((void*)dest)T(*source); }
-#endif
-
-template<class T, class U, class D>
-inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
-{
- new((void*)dest)T();
-}
-
-template<class InIt, class OutIt>
-struct optimize_assign
-{
- static const bool value = false;
-};
-
-template<class T>
-struct optimize_assign<const T*, T*>
-{
- static const bool value = boost::has_trivial_assign<T>::value;
-};
-
-template<class T>
-struct optimize_assign<T*, T*>
- : public optimize_assign<const T*, T*>
-{};
-
-template<class InIt, class OutIt>
-struct optimize_copy
-{
- static const bool value = false;
-};
-
-template<class T>
-struct optimize_copy<const T*, T*>
-{
- static const bool value = boost::has_trivial_copy<T>::value;
-};
-
-template<class T>
-struct optimize_copy<T*, T*>
- : public optimize_copy<const T*, T*>
-{};
-
-template<class InIt, class OutIt> inline
-OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, detail::bool_<false>)
-{
- for (; length--; ++dest, ++first)
- *dest = *first;
- return dest;
-}
-
-template<class T> inline
-T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, detail::bool_<true>)
-{
- std::size_t size = length*sizeof(T);
- return (static_cast<T*>(std::memmove(dest, first, size))) + size;
-}
-
-template<class InIt, class OutIt> inline
-OutIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
-{
- const bool do_optimized_assign = optimize_assign<InIt, OutIt>::value;
- return copy_n_dispatch(first, length, dest, detail::bool_<do_optimized_assign>());
-}
-
-template<class InIt, class FwdIt> inline
-FwdIt uninitialized_copy_n_dispatch
- (InIt first,
- typename std::iterator_traits<InIt>::difference_type count,
- FwdIt dest, detail::bool_<false>)
-{
- typedef typename std::iterator_traits<FwdIt>::value_type value_type;
- //Save initial destination position
- FwdIt dest_init = dest;
- typename std::iterator_traits<InIt>::difference_type new_count = count+1;
-
- BOOST_TRY{
- //Try to build objects
- for (; --new_count; ++dest, ++first){
- construct_in_place(detail::get_pointer(&*dest), first);
- }
- }
- BOOST_CATCH(...){
- //Call destructors
- new_count = count - new_count;
- for (; new_count--; ++dest_init){
- detail::get_pointer(&*dest_init)->~value_type();
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- return dest;
-}
-template<class T> inline
-T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, detail::bool_<true>)
-{
- std::size_t size = length*sizeof(T);
- return (static_cast<T*>(std::memmove(dest, first, size))) + size;
-}
-
-template<class InIt, class FwdIt> inline
-FwdIt uninitialized_copy_n
- (InIt first,
- typename std::iterator_traits<InIt>::difference_type count,
- FwdIt dest)
-{
- const bool do_optimized_copy = optimize_copy<InIt, FwdIt>::value;
- return uninitialized_copy_n_dispatch(first, count, dest, detail::bool_<do_optimized_copy>());
-}
-
-// uninitialized_copy_copy
-// Copies [first1, last1) into [result, result + (last1 - first1)), and
-// copies [first2, last2) into
-// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
-template <class InpIt1, class InpIt2, class FwdIt>
-FwdIt uninitialized_copy_copy
- (InpIt1 first1, InpIt1 last1, InpIt2 first2, InpIt2 last2, FwdIt result)
-{
- typedef typename std::iterator_traits<FwdIt>::value_type value_type;
- FwdIt mid = std::uninitialized_copy(first1, last1, result);
- BOOST_TRY {
- return std::uninitialized_copy(first2, last2, mid);
- }
- BOOST_CATCH(...){
- for(;result != mid; ++result){
- detail::get_pointer(&*result)->~value_type();
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
-}
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ALGORITHMS_HPP
-
Modified: trunk/boost/interprocess/detail/atomic.hpp
==============================================================================
--- trunk/boost/interprocess/detail/atomic.hpp (original)
+++ trunk/boost/interprocess/detail/atomic.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -48,7 +48,7 @@
} //namespace interprocess{
} //namespace boost{
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
#include <boost/interprocess/detail/win32_api.hpp>
Modified: trunk/boost/interprocess/detail/file_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/file_wrapper.hpp (original)
+++ trunk/boost/interprocess/detail/file_wrapper.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -24,7 +24,12 @@
class file_wrapper
{
+ /// @cond
+ file_wrapper(file_wrapper&);
+ file_wrapper & operator=(file_wrapper&);
+ /// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(file_wrapper)
//!Default constructor.
//!Represents an empty file_wrapper.
@@ -49,34 +54,18 @@
//!Moves the ownership of "moved"'s file to *this.
//!After the call, "moved" does not represent any file.
//!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- file_wrapper
- (detail::moved_object<file_wrapper> moved)
- { this->swap(moved.get()); }
- #else
- file_wrapper(file_wrapper &&moved)
+ file_wrapper(BOOST_INTERPROCESS_RV_REF(file_wrapper) moved)
{ this->swap(moved); }
- #endif
//!Moves the ownership of "moved"'s file to *this.
//!After the call, "moved" does not represent any file.
//!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- file_wrapper &operator=
- (detail::moved_object<file_wrapper> moved)
+ file_wrapper &operator=(BOOST_INTERPROCESS_RV_REF(file_wrapper) moved)
{
- file_wrapper tmp(moved);
+ file_wrapper tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
- #else
- file_wrapper &operator=(file_wrapper &&moved)
- {
- file_wrapper tmp(detail::move_impl(moved));
- this->swap(tmp);
- return *this;
- }
- #endif
//!Swaps to file_wrappers.
//!Does not throw
Deleted: trunk/boost/interprocess/detail/iterators.hpp
==============================================================================
--- trunk/boost/interprocess/detail/iterators.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,475 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008.
-// (C) Copyright Gennaro Prota 2003 - 2004.
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP
-#define BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-
-#include <iterator>
-#include <boost/interprocess/detail/type_traits.hpp>
-
-namespace boost {
-namespace interprocess {
-
-template <class T, class Difference = std::ptrdiff_t>
-class constant_iterator
- : public std::iterator
- <std::random_access_iterator_tag, T, Difference, const T*, const T &>
-{
- typedef constant_iterator<T, Difference> this_type;
-
- public:
- explicit constant_iterator(const T &ref, Difference range_size)
- : m_ptr(&ref), m_num(range_size){}
-
- //Constructors
- constant_iterator()
- : m_ptr(0), m_num(0){}
-
- constant_iterator& operator++()
- { increment(); return *this; }
-
- constant_iterator operator++(int)
- {
- constant_iterator result (*this);
- increment();
- return result;
- }
-
- friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
- { return i.equal(i2); }
-
- friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
- { return !(i == i2); }
-
- friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
- { return i.less(i2); }
-
- friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
- { return i2 < i; }
-
- friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
- { return !(i > i2); }
-
- friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
- { return !(i < i2); }
-
- friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
- { return i2.distance_to(i); }
-
- //Arithmetic
- constant_iterator& operator+=(Difference off)
- { this->advance(off); return *this; }
-
- constant_iterator operator+(Difference off) const
- {
- constant_iterator other(*this);
- other.advance(off);
- return other;
- }
-
- friend constant_iterator operator+(Difference off, const constant_iterator& right)
- { return right + off; }
-
- constant_iterator& operator-=(Difference off)
- { this->advance(-off); return *this; }
-
- constant_iterator operator-(Difference off) const
- { return *this + (-off); }
-
- const T& operator*() const
- { return dereference(); }
-
- const T* operator->() const
- { return &(dereference()); }
-
- private:
- const T * m_ptr;
- Difference m_num;
-
- void increment()
- { --m_num; }
-
- void decrement()
- { ++m_num; }
-
- bool equal(const this_type &other) const
- { return m_num == other.m_num; }
-
- bool less(const this_type &other) const
- { return other.m_num < m_num; }
-
- const T & dereference() const
- { return *m_ptr; }
-
- void advance(Difference n)
- { m_num -= n; }
-
- Difference distance_to(const this_type &other)const
- { return m_num - other.m_num; }
-};
-
-template <class T, class Difference = std::ptrdiff_t>
-class default_construct_iterator
- : public std::iterator
- <std::random_access_iterator_tag, T, Difference, const T*, const T &>
-{
- typedef default_construct_iterator<T, Difference> this_type;
-
- public:
- explicit default_construct_iterator(Difference range_size)
- : m_num(range_size){}
-
- //Constructors
- default_construct_iterator()
- : m_num(0){}
-
- default_construct_iterator& operator++()
- { increment(); return *this; }
-
- default_construct_iterator operator++(int)
- {
- default_construct_iterator result (*this);
- increment();
- return result;
- }
-
- friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return i.equal(i2); }
-
- friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return !(i == i2); }
-
- friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return i.less(i2); }
-
- friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return i2 < i; }
-
- friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return !(i > i2); }
-
- friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return !(i < i2); }
-
- friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
- { return i2.distance_to(i); }
-
- //Arithmetic
- default_construct_iterator& operator+=(Difference off)
- { this->advance(off); return *this; }
-
- default_construct_iterator operator+(Difference off) const
- {
- default_construct_iterator other(*this);
- other.advance(off);
- return other;
- }
-
- friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
- { return right + off; }
-
- default_construct_iterator& operator-=(Difference off)
- { this->advance(-off); return *this; }
-
- default_construct_iterator operator-(Difference off) const
- { return *this + (-off); }
-
- const T& operator*() const
- { return dereference(); }
-
- const T* operator->() const
- { return &(dereference()); }
-
- private:
- Difference m_num;
-
- void increment()
- { --m_num; }
-
- void decrement()
- { ++m_num; }
-
- bool equal(const this_type &other) const
- { return m_num == other.m_num; }
-
- bool less(const this_type &other) const
- { return other.m_num < m_num; }
-
- const T & dereference() const
- {
- static T dummy;
- return dummy;
- }
-
- void advance(Difference n)
- { m_num -= n; }
-
- Difference distance_to(const this_type &other)const
- { return m_num - other.m_num; }
-};
-
-template <class T, class Difference = std::ptrdiff_t>
-class repeat_iterator
- : public std::iterator
- <std::random_access_iterator_tag, T, Difference>
-{
- typedef repeat_iterator<T, Difference> this_type;
- public:
- explicit repeat_iterator(T &ref, Difference range_size)
- : m_ptr(&ref), m_num(range_size){}
-
- //Constructors
- repeat_iterator()
- : m_ptr(0), m_num(0){}
-
- this_type& operator++()
- { increment(); return *this; }
-
- this_type operator++(int)
- {
- this_type result (*this);
- increment();
- return result;
- }
-
- friend bool operator== (const this_type& i, const this_type& i2)
- { return i.equal(i2); }
-
- friend bool operator!= (const this_type& i, const this_type& i2)
- { return !(i == i2); }
-
- friend bool operator< (const this_type& i, const this_type& i2)
- { return i.less(i2); }
-
- friend bool operator> (const this_type& i, const this_type& i2)
- { return i2 < i; }
-
- friend bool operator<= (const this_type& i, const this_type& i2)
- { return !(i > i2); }
-
- friend bool operator>= (const this_type& i, const this_type& i2)
- { return !(i < i2); }
-
- friend Difference operator- (const this_type& i, const this_type& i2)
- { return i2.distance_to(i); }
-
- //Arithmetic
- this_type& operator+=(Difference off)
- { this->advance(off); return *this; }
-
- this_type operator+(Difference off) const
- {
- this_type other(*this);
- other.advance(off);
- return other;
- }
-
- friend this_type operator+(Difference off, const this_type& right)
- { return right + off; }
-
- this_type& operator-=(Difference off)
- { this->advance(-off); return *this; }
-
- this_type operator-(Difference off) const
- { return *this + (-off); }
-
- T& operator*() const
- { return dereference(); }
-
- T *operator->() const
- { return &(dereference()); }
-
- private:
- T * m_ptr;
- Difference m_num;
-
- void increment()
- { --m_num; }
-
- void decrement()
- { ++m_num; }
-
- bool equal(const this_type &other) const
- { return m_num == other.m_num; }
-
- bool less(const this_type &other) const
- { return other.m_num < m_num; }
-
- T & dereference() const
- { return *m_ptr; }
-
- void advance(Difference n)
- { m_num -= n; }
-
- Difference distance_to(const this_type &other)const
- { return m_num - other.m_num; }
-};
-
-template <class PseudoReference>
-struct operator_arrow_proxy
-{
- operator_arrow_proxy(const PseudoReference &px)
- : m_value(px)
- {}
-
- PseudoReference* operator->() const { return &m_value; }
- // This function is needed for MWCW and BCC, which won't call operator->
- // again automatically per 13.3.1.2 para 8
-// operator T*() const { return &m_value; }
- mutable PseudoReference m_value;
-};
-
-template <class T>
-struct operator_arrow_proxy<T&>
-{
- operator_arrow_proxy(T &px)
- : m_value(px)
- {}
-
- T* operator->() const { return &m_value; }
- // This function is needed for MWCW and BCC, which won't call operator->
- // again automatically per 13.3.1.2 para 8
-// operator T*() const { return &m_value; }
- mutable T &m_value;
-};
-
-template <class Iterator, class UnaryFunction>
-class transform_iterator
- : public UnaryFunction
- , public std::iterator
- < typename Iterator::iterator_category
- , typename detail::remove_reference<typename UnaryFunction::result_type>::type
- , typename Iterator::difference_type
- , operator_arrow_proxy<typename UnaryFunction::result_type>
- , typename UnaryFunction::result_type>
-{
- public:
- explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
- : UnaryFunction(f), m_it(it)
- {}
-
- explicit transform_iterator()
- : UnaryFunction(), m_it()
- {}
-
- //Constructors
- transform_iterator& operator++()
- { increment(); return *this; }
-
- transform_iterator operator++(int)
- {
- transform_iterator result (*this);
- increment();
- return result;
- }
-
- friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
- { return i.equal(i2); }
-
- friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
- { return !(i == i2); }
-
-/*
- friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
- { return i2 < i; }
-
- friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
- { return !(i > i2); }
-
- friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
- { return !(i < i2); }
-*/
- friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
- { return i2.distance_to(i); }
-
- //Arithmetic
- transform_iterator& operator+=(typename Iterator::difference_type off)
- { this->advance(off); return *this; }
-
- transform_iterator operator+(typename Iterator::difference_type off) const
- {
- transform_iterator other(*this);
- other.advance(off);
- return other;
- }
-
- friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
- { return right + off; }
-
- transform_iterator& operator-=(typename Iterator::difference_type off)
- { this->advance(-off); return *this; }
-
- transform_iterator operator-(typename Iterator::difference_type off) const
- { return *this + (-off); }
-
- typename UnaryFunction::result_type operator*() const
- { return dereference(); }
-
- operator_arrow_proxy<typename UnaryFunction::result_type>
- operator->() const
- { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
-
- Iterator & base()
- { return m_it; }
-
- const Iterator & base() const
- { return m_it; }
-
- private:
- Iterator m_it;
-
- void increment()
- { ++m_it; }
-
- void decrement()
- { --m_it; }
-
- bool equal(const transform_iterator &other) const
- { return m_it == other.m_it; }
-
- bool less(const transform_iterator &other) const
- { return other.m_it < m_it; }
-
- typename UnaryFunction::result_type dereference() const
- { return UnaryFunction::operator()(*m_it); }
-
- void advance(typename Iterator::difference_type n)
- { std::advance(m_it, n); }
-
- typename Iterator::difference_type distance_to(const transform_iterator &other)const
- { return std::distance(other.m_it, m_it); }
-};
-
-template <class Iterator, class UnaryFunc>
-transform_iterator<Iterator, UnaryFunc>
-make_transform_iterator(Iterator it, UnaryFunc fun)
-{
- return transform_iterator<Iterator, UnaryFunc>(it, fun);
-}
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_DETAIL_ITERATORS_HPP
-
Modified: trunk/boost/interprocess/detail/managed_memory_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_memory_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_memory_impl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -98,7 +98,7 @@
segment_manager::char_ptr_holder_t char_ptr_holder_t;
//Experimental. Don't use.
- typedef typename segment_manager::multiallocation_iterator multiallocation_iterator;
+ typedef typename segment_manager::multiallocation_chain multiallocation_chain;
/// @endcond
@@ -291,7 +291,7 @@
template<class T>
std::pair<T *, bool>
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr = 0)
{
@@ -310,21 +310,25 @@
//Experimental. Don't use.
//!Allocates n_elements of elem_size bytes.
- multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements)
+ multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements)
{ return mp_header->allocate_many(elem_bytes, num_elements); }
//!Allocates n_elements, each one of elem_sizes[i] bytes.
- multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements)
+ multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements)
{ return mp_header->allocate_many(elem_sizes, n_elements); }
//!Allocates n_elements of elem_size bytes.
- multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t nothrow)
+ multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t nothrow)
{ return mp_header->allocate_many(elem_bytes, num_elements, nothrow); }
//!Allocates n_elements, each one of elem_sizes[i] bytes.
- multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow)
+ multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow)
{ return mp_header->allocate_many(elem_sizes, n_elements, nothrow); }
+ //!Allocates n_elements, each one of elem_sizes[i] bytes.
+ void deallocate_many(multiallocation_chain chain)
+ { return mp_header->deallocate_many(boost::interprocess::move(chain)); }
+
/// @endcond
//!Marks previously allocated memory as free. Never throws.
Modified: trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp (original)
+++ trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -315,21 +315,21 @@
case create_open_func::DoCreate:
{
managed_impl shm(create_only, name, size, read_write, addr, func);
- mshm = detail::move_impl(shm);
+ mshm = boost::interprocess::move(shm);
}
break;
case create_open_func::DoOpen:
{
managed_impl shm(open_only, name,read_write, addr, func);
- mshm = detail::move_impl(shm);
+ mshm = boost::interprocess::move(shm);
}
break;
case create_open_func::DoOpenOrCreate:
{
managed_impl shm(open_or_create, name, size, read_write, addr, func);
- mshm = detail::move_impl(shm);
+ mshm = boost::interprocess::move(shm);
}
break;
@@ -339,7 +339,7 @@
}
//This can throw.
- m_shmem_list.push_back(detail::move_impl(mshm));
+ m_shmem_list.push_back(boost::interprocess::move(mshm));
return true;
}
BOOST_CATCH(const std::bad_alloc&){
Modified: trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -37,8 +37,8 @@
class managed_open_or_create_impl
{
//Non-copyable
- managed_open_or_create_impl(const managed_open_or_create_impl &);
- managed_open_or_create_impl &operator=(const managed_open_or_create_impl &);
+ managed_open_or_create_impl(managed_open_or_create_impl &);
+ managed_open_or_create_impl &operator=(managed_open_or_create_impl &);
enum
{
@@ -49,6 +49,7 @@
};
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(managed_open_or_create_impl)
static const std::size_t
ManagedOpenOrCreateUserOffset =
@@ -154,34 +155,16 @@
, construct_func);
}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- managed_open_or_create_impl(detail::moved_object<managed_open_or_create_impl> moved)
- { this->swap(moved.get()); }
- #else
- managed_open_or_create_impl(managed_open_or_create_impl &&moved)
+ managed_open_or_create_impl(BOOST_INTERPROCESS_RV_REF(managed_open_or_create_impl) moved)
{ this->swap(moved); }
- #endif
- //!Move assignment. If *this owns a memory mapped region, it will be
- //!destroyed and it will take ownership of "other"'s memory mapped region.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- managed_open_or_create_impl &operator=(detail::moved_object<managed_open_or_create_impl> moved)
+ managed_open_or_create_impl &operator=(BOOST_INTERPROCESS_RV_REF(managed_open_or_create_impl) moved)
{
- managed_open_or_create_impl tmp(moved);
+ managed_open_or_create_impl tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
- #else
- managed_open_or_create_impl &operator=(managed_open_or_create_impl &&moved)
- {
- managed_open_or_create_impl tmp(detail::move_impl(moved));
- this->swap(tmp);
- return *this;
- }
- #endif
-
~managed_open_or_create_impl()
{}
@@ -437,20 +420,6 @@
} //namespace detail {
-
-///@cond
-
-//!Trait class to detect if a type is
-//!movable
-template<class DeviceAbstraction>
-
-struct is_movable<detail::managed_open_or_create_impl<DeviceAbstraction> >
-{
- enum { value = true };
-};
-
-///@endcond
-
} //namespace interprocess {
} //namespace boost {
Modified: trunk/boost/interprocess/detail/move.hpp
==============================================================================
--- trunk/boost/interprocess/detail/move.hpp (original)
+++ trunk/boost/interprocess/detail/move.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,175 +1,749 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
//
-// See http://www.boost.org/libs/interprocess for documentation.
+// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
+//
+// Parts of this file come from Adobe's Move library:
+//
+// Copyright 2005-2007 Adobe Systems Incorporated
+// Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
+// or a copy at http://stlab.adobe.com/licenses.html)
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
#ifndef BOOST_INTERPROCESS_MOVE_HPP
#define BOOST_INTERPROCESS_MOVE_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
+#include <boost/config.hpp>
+#include <algorithm> //copy, copy_backward
+#include <memory> //uninitialized_copy
+#include <iterator> //std::iterator
+#include <boost/mpl/if.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace move_detail {
+
+template <class T>
+struct identity
+{
+ typedef T type;
+};
+
+template <class T, class U>
+class is_convertible
+{
+ typedef char true_t;
+ class false_t { char dummy[2]; };
+ static true_t dispatch(U);
+ static false_t dispatch(...);
+ static T trigger();
+ public:
+ enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+};
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
+} //namespace move_detail {
+} //namespace interprocess {
+} //namespace boost {
-//!\file
-//!Describes a function and a type to emulate move semantics.
+#if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
namespace boost {
namespace interprocess {
-//!Trait class to detect if a type is
-//!movable
+//////////////////////////////////////////////////////////////////////////////
+//
+// struct rv
+//
+//////////////////////////////////////////////////////////////////////////////
+template <class T>
+class rv : public T
+{
+ rv();
+ ~rv();
+ rv(rv const&);
+ void operator=(rv const&);
+
+ public:
+ //T &get() { return *this; }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// move_detail::is_rv
+//
+//////////////////////////////////////////////////////////////////////////////
+
+namespace move_detail {
+
template <class T>
-struct is_movable
+struct is_rv
{
- enum { value = false };
+ static const bool value = false;
};
+template <class T>
+struct is_rv< rv<T> >
+{
+ static const bool value = true;
+};
+
+} //namespace move_detail {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// is_movable
+//
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+class is_movable
+{
+ public:
+ static const bool value = move_detail::is_convertible<T, rv<T>&>::value;
+};
+
+template<class T>
+class is_movable< rv<T> >
+{
+ public:
+ static const bool value = false;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// move()
+//
+//////////////////////////////////////////////////////////////////////////////
+template <class T>
+typename boost::disable_if<is_movable<T>, T&>::type move(T& x)
+{
+ return x;
+}
+
+template <class T>
+typename enable_if<is_movable<T>, rv<T>&>::type move(T& x)
+{
+ return static_cast<rv<T>& >(x);
+}
+
+template <class T>
+typename enable_if<is_movable<T>, rv<T>&>::type move(const rv<T>& x)
+{
+ return const_cast<rv<T>& >(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// forward()
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+typename enable_if<boost::interprocess::move_detail::is_rv<T>, T &>::type
+ forward(const typename move_detail::identity<T>::type &x)
+{
+ return const_cast<T&>(x);
+}
+
+/*
+template <class T>
+typename enable_if<boost::interprocess::move_detail::is_rv<T>, T &>::type
+forward(typename move_detail::identity<T>::type &x)
+{
+ return x;
+}
+
+template <class T>
+typename disable_if<boost::interprocess::move_detail::is_rv<T>, T &>::type
+ forward(typename move_detail::identity<T>::type &x)
+{
+ return x;
+}
+*/
+template <class T>
+typename disable_if<boost::interprocess::move_detail::is_rv<T>, const T &>::type
+ forward(const typename move_detail::identity<T>::type &x)
+{
+ return x;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION
+//
+//////////////////////////////////////////////////////////////////////////////
+#define BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(TYPE)\
+ operator boost::interprocess::rv<TYPE>&() \
+ { return static_cast<boost::interprocess::rv<TYPE>& >(*this); }\
+ operator const boost::interprocess::rv<TYPE>&() \
+ { return static_cast<const boost::interprocess::rv<TYPE>& >(*this); }\
+//
+
+
+#define BOOST_INTERPROCESS_RV_REF(TYPE)\
+ boost::interprocess::rv< TYPE >& \
+//
+
+#define BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+ boost::interprocess::rv< TYPE<ARG1, ARG2> >& \
+//
+
+#define BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+ boost::interprocess::rv< TYPE<ARG1, ARG2, ARG3> >& \
+//
+
+#define BOOST_INTERPROCESS_FWD_REF(TYPE)\
+ const TYPE & \
+//
} //namespace interprocess {
-} //namespace boost {
+} //namespace boost
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#else //BOOST_HAS_RVALUE_REFS
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/type_traits/remove_reference.hpp>
namespace boost {
namespace interprocess {
-namespace detail {
-//!An object that represents a
-//!moved object.
+//////////////////////////////////////////////////////////////////////////////
+//
+// is_movable
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! For compilers with rvalue references, this traits class returns true
+//! if T && is convertible to T.
+//!
+//! For other compilers returns true if T is convertible to <i>boost::interprocess::rv<T>&</i>
template<class T>
-struct moved_object
-{
- moved_object(const T &obj)
- : m_obj(const_cast<T *>(&obj))
+class is_movable
+{
+ public:
+ static const bool value = move_detail::is_convertible<T&&, T>::value;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+//! This function provides a way to convert a reference into a rvalue reference
+//! in compilers with rvalue reference. For other compilers converts T & into
+//! <i>boost::interprocess::rv<T> &</i> so that move emulation is activated.
+template <class T> inline
+rvalue_reference move (input_reference);
+#else
+template <class T> inline
+typename remove_reference<T>::type&& move(T&& t)
+{ return t; }
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// forward
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+//! This function provides limited form of forwarding that is usually enough for
+//! in-place construction and avoids the exponential overloading necessary for
+//! perfect forwarding in C++03.
+//!
+//! For compilers with rvalue references this function provides perfect forwarding.
+//!
+//! Otherwise:
+//! * If input_reference binds to const boost::interprocess::rv<T> & then it output_reference is
+//! boost::rev<T> &
+//!
+//! * Else, input_reference is equal to output_reference is equal to input_reference.
+template <class T> inline output_reference forward(input_reference);
+#else
+template <class T> inline
+T&& forward (typename move_detail::identity<T>::type&& t)
+{ return t; }
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! This macro expands to nothing for compilers with rvalue references.
+//! Otherwise expands to:
+//! \code
+//! operator boost::interprocess::rv<TYPE>&()
+//! { return static_cast<boost::interprocess::rv<TYPE>& >(*this); }
+//! \endcode
+#define BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(TYPE)\
+//
+
+#define BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+ TYPE<ARG1, ARG2> && \
+//
+
+#define BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+ TYPE<ARG1, ARG2, ARG3> && \
+//
+
+//! This macro expands to <i>T&&</i> for compilers with rvalue references.
+//! Otherwise expands to <i>boost::interprocess::rv<T> &</i>.
+#define BOOST_INTERPROCESS_RV_REF(TYPE)\
+ TYPE && \
+//
+
+//! This macro expands to <i>T&&</i> for compilers with rvalue references.
+//! Otherwise expands to <i>const T &</i>.
+#define BOOST_INTERPROCESS_FWD_REF(TYPE)\
+ TYPE && \
+//
+
+} //namespace interprocess {
+} //namespace boost {
+
+#endif //BOOST_HAS_RVALUE_REFS
+
+namespace boost {
+namespace interprocess {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! Class template move_iterator is an iterator adaptor with the same behavior
+//! as the underlying iterator except that its dereference operator implicitly
+//! converts the value returned by the underlying iterator's dereference operator
+//! to an rvalue reference. Some generic algorithms can be called with move
+//! iterators to replace copying with moving.
+template <class It>
+class move_iterator
+{
+ public:
+ typedef It iterator_type;
+ typedef typename std::iterator_traits<iterator_type>::value_type value_type;
+ #if defined(BOOST_HAS_RVALUE_REFS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ typedef value_type && reference;
+ #else
+ typedef typename boost::mpl::if_
+ < boost::interprocess::is_movable<value_type>
+ , boost::interprocess::rv<value_type>&
+ , value_type & >::type reference;
+ #endif
+ typedef typename std::iterator_traits<iterator_type>::pointer pointer;
+ typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
+ typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
+
+ move_iterator()
+ {}
+
+ explicit move_iterator(It i)
+ : m_it(i)
+ {}
+
+ template <class U>
+ move_iterator(const move_iterator<U>& u)
+ : m_it(u.base())
{}
- T &get() const
- { return *m_obj; }
+ iterator_type base() const
+ { return m_it; }
+
+ reference operator*() const
+ {
+ #if defined(BOOST_HAS_RVALUE_REFS)
+ return *m_it;
+ #else
+ return boost::interprocess::move(*m_it);
+ #endif
+ }
+
+ pointer operator->() const
+ { return m_it; }
+
+ move_iterator& operator++()
+ { ++m_it; return *this; }
+
+ move_iterator<iterator_type> operator++(int)
+ { move_iterator<iterator_type> tmp(*this); ++(*this); return tmp; }
+
+ move_iterator& operator--()
+ { --m_it; return *this; }
+
+ move_iterator<iterator_type> operator--(int)
+ { move_iterator<iterator_type> tmp(*this); --(*this); return tmp; }
+
+ move_iterator<iterator_type> operator+ (difference_type n) const
+ { return move_iterator<iterator_type>(m_it + n); }
+
+ move_iterator& operator+=(difference_type n)
+ { m_it += n; return *this; }
+
+ move_iterator<iterator_type> operator- (difference_type n) const
+ { return move_iterator<iterator_type>(m_it - n); }
+
+ move_iterator& operator-=(difference_type n)
+ { m_it -= n; return *this; }
+
+ reference operator[](difference_type n) const
+ {
+ #if defined(BOOST_HAS_RVALUE_REFS)
+ return m_it[n];
+ #else
+ return boost::interprocess::move(m_it[n]);
+ #endif
+ }
+
+ friend bool operator==(const move_iterator& x, const move_iterator& y)
+ { return x.base() == y.base(); }
+
+ friend bool operator!=(const move_iterator& x, const move_iterator& y)
+ { return x.base() != y.base(); }
+
+ friend bool operator< (const move_iterator& x, const move_iterator& y)
+ { return x.base() < y.base(); }
+
+ friend bool operator<=(const move_iterator& x, const move_iterator& y)
+ { return x.base() <= y.base(); }
+
+ friend bool operator> (const move_iterator& x, const move_iterator& y)
+ { return x.base() > y.base(); }
+
+ friend bool operator>=(const move_iterator& x, const move_iterator& y)
+ { return x.base() >= y.base(); }
+
+ friend difference_type operator-(const move_iterator& x, const move_iterator& y)
+ { return x.base() - y.base(); }
+
+ friend move_iterator operator+(difference_type n, const move_iterator& x)
+ { return move_iterator(x.base() + n); }
private:
- T *m_obj;
+ It m_it;
};
-// Metafunction that, given movable T, provides move_source<T>, else T&.
-template <typename T>
-struct move_type
+
+//is_move_iterator
+namespace move_detail {
+
+template <class I>
+struct is_move_iterator
{
- public: // metafunction result
- typedef typename if_<is_movable<T>, moved_object<T>, T&>::type type;
+ static const bool value = false;
};
-template <typename T>
-class move_return
+template <class I>
+struct is_move_iterator< ::boost::interprocess::move_iterator<I> >
{
- typedef moved_object<T> moved_type;
- private:
- mutable T m_moved;
+ static const bool value = true;
+};
+
+} //namespace move_detail {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//!
+//! <b>Returns</b>: move_iterator<It>(i).
+template<class It>
+move_iterator<It> make_move_iterator(const It &it)
+{ return move_iterator<It>(it); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// back_move_insert_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+//! A move insert iterator that move constructs elements at the
+//! back of a container
+template <typename C> // C models Container
+class back_move_insert_iterator
+ : public std::iterator<std::output_iterator_tag, void, void, void, void>
+{
+ C* container_m;
+
public:
- typedef T type;
+ typedef C container_type;
- move_return(const T& returned)
- : m_moved(moved_object<T>(returned))
- {}
+ explicit back_move_insert_iterator(C& x) : container_m(&x) { }
- move_return(const move_return& operand)
- : m_moved(const_cast<move_return&>(operand))
- {}
+ back_move_insert_iterator& operator=(typename C::reference x)
+ { container_m->push_back(boost::interprocess::move(x)); return *this; }
+
+ back_move_insert_iterator& operator*() { return *this; }
+ back_move_insert_iterator& operator++() { return *this; }
+ back_move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: back_move_insert_iterator<C>(x).
+template <typename C> // C models Container
+inline back_move_insert_iterator<C> back_move_inserter(C& x)
+{
+ return back_move_insert_iterator<C>(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// front_move_insert_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! A move insert iterator that move constructs elements int the
+//! front of a container
+template <typename C> // C models Container
+class front_move_insert_iterator
+ : public std::iterator<std::output_iterator_tag, void, void, void, void>
+{
+ C* container_m;
+
+public:
+ typedef C container_type;
+
+ explicit front_move_insert_iterator(C& x) : container_m(&x) { }
- operator moved_type() const
- { return moved_type(m_moved); }
+ front_move_insert_iterator& operator=(typename C::reference x)
+ { container_m->push_front(boost::interprocess::move(x)); return *this; }
+
+ front_move_insert_iterator& operator*() { return *this; }
+ front_move_insert_iterator& operator++() { return *this; }
+ front_move_insert_iterator& operator++(int) { return *this; }
};
-template <typename T>
-struct return_type
+//!
+//! <b>Returns</b>: front_move_insert_iterator<C>(x).
+template <typename C> // C models Container
+inline front_move_insert_iterator<C> front_move_inserter(C& x)
+{
+ return front_move_insert_iterator<C>(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// insert_move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+template <typename C> // C models Container
+class move_insert_iterator
+ : public std::iterator<std::output_iterator_tag, void, void, void, void>
{
- public: // metafunction result
+ C* container_m;
+ typename C::iterator pos_;
- typedef typename if_<is_movable<T>, move_return<T>, T>::type type;
+ public:
+ typedef C container_type;
+
+ explicit move_insert_iterator(C& x, typename C::iterator pos)
+ : container_m(&x), pos_(pos)
+ {}
+
+ move_insert_iterator& operator=(typename C::reference x)
+ {
+ pos_ = container_m->insert(pos_, boost::interprocess::move(x));
+ ++pos_;
+ return *this;
+ }
+
+ move_insert_iterator& operator*() { return *this; }
+ move_insert_iterator& operator++() { return *this; }
+ move_insert_iterator& operator++(int) { return *this; }
};
-} //namespace detail {
-} //namespace interprocess {
-} //namespace boost {
+//!
+//! <b>Returns</b>: move_insert_iterator<C>(x, it).
+template <typename C> // C models Container
+inline move_insert_iterator<C> move_inserter(C& x, typename C::iterator it)
+{
+ return move_insert_iterator<C>(x, it);
+}
-namespace boost {
-namespace interprocess {
+//////////////////////////////////////////////////////////////////////////////
+//
+// move
+//
+//////////////////////////////////////////////////////////////////////////////
-namespace detail{
-//!A function that converts an object to a moved object so that
-//!it can match a function taking a detail::moved_object object.
-template<class Object>
-typename detail::move_type<Object>::type move_impl(const Object &object)
-{
- typedef typename detail::move_type<Object>::type type;
- return type(object);
+//! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
+//! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
+//! performs *(result + n) = boost::interprocess::move (*(first + n)).
+//!
+//! <b>Effects</b>: result + (last - first).
+//!
+//! <b>Requires</b>: result shall not be in the range [first,last).
+//!
+//! <b>Complexity</b>: Exactly last - first move assignments.
+template <typename I, // I models InputIterator
+ typename O> // O models OutputIterator
+O move(I f, I l, O result)
+{
+ while (f != l) {
+ *result = boost::interprocess::move(*f);
+ ++f; ++result;
+ }
+ return result;
}
-template <class T>
-inline const T& forward_impl(const T &t)
-{ return t; }
+//////////////////////////////////////////////////////////////////////////////
+//
+// move_backward
+//
+//////////////////////////////////////////////////////////////////////////////
-template <class T>
-inline T& forward_impl(T &t)
-{ return t; }
+//! <b>Effects</b>: Moves elements in the range [first,last) into the range
+//! [result - (last-first),result) starting from last - 1 and proceeding to
+//! first. For each positive integer n <= (last - first),
+//! performs *(result - n) = boost::interprocess::move(*(last - n)).
+//!
+//! <b>Requires</b>: result shall not be in the range [first,last).
+//!
+//! <b>Returns</b>: result - (last - first).
+//!
+//! <b>Complexity</b>: Exactly last - first assignments.
+template <typename I, // I models BidirectionalIterator
+typename O> // O models BidirectionalIterator
+O move_backward(I f, I l, O result)
+{
+ while (f != l) {
+ --l; --result;
+ *result = boost::interprocess::move(*l);
+ }
+ return result;
+}
-template <class T>
-inline detail::moved_object<T> forward_impl(detail::moved_object<T> &t)
-{ return t; }
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; first != last; ++result, ++first)
+//! new (static_cast<void*>(&*result))
+//! typename iterator_traits<ForwardIterator>::value_type(boost::interprocess::move(*first));
+//! \endcode
+//!
+//! <b>Returns</b>: result
+template
+ <typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+F uninitialized_move(I f, I l, F r
+ /// @cond
+ ,typename enable_if<is_movable<typename std::iterator_traits<I>::value_type> >::type* = 0
+ /// @endcond
+ )
+{
+ typedef typename std::iterator_traits<I>::value_type input_value_type;
+ while (f != l) {
+ ::new(static_cast<void*>(&*r)) input_value_type(boost::interprocess::move(*f));
+ ++f; ++r;
+ }
+ return r;
+}
-} //namespace detail {
+/// @cond
-//!A function that converts an object to a moved object so that
-//!it can match a function taking a detail::moved_object object.
-template<class Object>
-typename detail::move_type<Object>::type move(const Object &object)
-{ return detail::move_impl(object); }
+template
+ <typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+F uninitialized_move(I f, I l, F r,
+ typename disable_if<is_movable<typename std::iterator_traits<I>::value_type> >::type* = 0)
+{
+ return std::uninitialized_copy(f, l, r);
+}
-} //namespace interprocess {
-} //namespace boost {
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
-#else //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+namespace move_detail {
-#include <boost/interprocess/detail/type_traits.hpp>
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+F uninitialized_move_move_iterator(I f, I l, F r,
+ typename enable_if< is_movable<typename I::value_type> >::type* = 0)
+{
+ return boost::interprocess::uninitialized_move(f, l, r);
+}
-namespace boost {
-namespace interprocess {
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+F uninitialized_move_move_iterator(I f, I l, F r,
+ typename disable_if< is_movable<typename I::value_type> >::type* = 0)
+{
+ return std::uninitialized_copy(f.base(), l.base(), r);
+}
-namespace detail {
+} //namespace move_detail {
-template <class T>
-inline typename detail::remove_reference<T>::type&& move_impl(T&& t)
-{ return t; }
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+F uninitialized_copy_or_move(I f, I l, F r,
+ typename enable_if< move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return boost::interprocess::move_detail::uninitialized_move_move_iterator(f, l, r);
+}
-template <class T>
-inline T&& forward_impl(typename detail::identity<T>::type&& t)
-{ return t; }
+/// @endcond
-} //namespace detail {
+//! <b>Effects</b>:
+//! \code
+//! for (; first != last; ++result, ++first)
+//! new (static_cast<void*>(&*result))
+//! typename iterator_traits<ForwardIterator>::value_type(*first);
+//! \endcode
+//!
+//! <b>Returns</b>: result
+//!
+//! <b>Note</b>: This function is provided because
+//! <i>std::uninitialized_copy</i> from some STL implementations
+//! is not compatible with <i>move_iterator</i>
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+F uninitialized_copy_or_move(I f, I l, F r
+ /// @cond
+ ,typename disable_if< move_detail::is_move_iterator<I> >::type* = 0
+ /// @endcond
+ )
+{
+ return std::uninitialized_copy(f, l, r);
+}
+///has_trivial_destructor_after_move<> == true_type
+///specialization for optimizations
template <class T>
-inline typename detail::remove_reference<T>::type&& move(T&& t)
-{ return t; }
+struct has_trivial_destructor_after_move
+ : public boost::has_trivial_destructor<T>
+{};
} //namespace interprocess {
} //namespace boost {
-#endif //#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_MOVE_HPP
+#endif //#ifndef BOOST_INTERPROCESS_MOVE_HPP
Deleted: trunk/boost/interprocess/detail/move_iterator.hpp
==============================================================================
--- trunk/boost/interprocess/detail/move_iterator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,138 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_MOVE_ITERATOR_HPP_INCLUDED
-#define BOOST_INTERPROCESS_MOVE_ITERATOR_HPP_INCLUDED
-
-#include <iterator>
-#include <boost/interprocess/detail/move.hpp>
-
-namespace boost{
-namespace interprocess{
-namespace detail{
-
-template <class It>
-class move_iterator
-{
- public:
- typedef It iterator_type;
- typedef typename std::iterator_traits<iterator_type>::value_type value_type;
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- typedef typename move_type<value_type>::type reference;
- #else
- typedef value_type && reference;
- #endif
- typedef typename std::iterator_traits<iterator_type>::pointer pointer;
- typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
- typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
-
- move_iterator()
- {}
-
- explicit move_iterator(It i)
- : m_it(i)
- {}
-
- template <class U>
- move_iterator(const move_iterator<U>& u)
- : m_it(u.base())
- {}
-
- const iterator_type &base() const
- { return m_it; }
-
- iterator_type &base()
- { return m_it; }
-
- reference operator*() const
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- { return detail::move_impl(*m_it); }
- #else
- { return *m_it; }
- #endif
-
- pointer operator->() const
- { return m_it; }
-
- move_iterator& operator++()
- { ++m_it; return *this; }
-
- move_iterator<iterator_type> operator++(int)
- { move_iterator<iterator_type> tmp(*this); ++(*this); return tmp; }
-
- move_iterator& operator--()
- { --m_it; return *this; }
-
- move_iterator<iterator_type> operator--(int)
- { move_iterator<iterator_type> tmp(*this); --(*this); return tmp; }
-
- move_iterator<iterator_type> operator+ (difference_type n) const
- { return move_iterator<iterator_type>(m_it + n); }
-
- move_iterator& operator+=(difference_type n)
- { m_it += n; return *this; }
-
- move_iterator<iterator_type> operator- (difference_type n) const
- { return move_iterator<iterator_type>(m_it - n); }
-
- move_iterator& operator-=(difference_type n)
- { m_it -= n; return *this; }
-
- reference operator[](difference_type n) const
- { return detail::move_impl(m_it[n]); }
-
- private:
- It m_it;
-};
-
-template <class It> inline
-bool operator==(const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() == y.base(); }
-
-template <class It> inline
-bool operator!=(const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() != y.base(); }
-
-template <class It> inline
-bool operator< (const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() < y.base(); }
-
-template <class It> inline
-bool operator<=(const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() <= y.base(); }
-
-template <class It> inline
-bool operator> (const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() > y.base(); }
-
-template <class It> inline
-bool operator>=(const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() >= y.base(); }
-
-template <class It> inline
-typename move_iterator<It>::difference_type
- operator-(const move_iterator<It>& x, const move_iterator<It>& y)
-{ return x.base() - y.base(); }
-
-template <class It> inline
-move_iterator<It>
- operator+(typename move_iterator<It>::difference_type n
- ,const move_iterator<It>& x)
-{ return move_iterator<It>(x.base() + n); }
-
-template<class It>
-move_iterator<It> make_move_iterator(const It &it)
-{ return move_iterator<It>(it); }
-
-} //namespace detail{
-} //namespace interprocess{
-} //namespace boost{
-
-#endif //#ifndef BOOST_INTERPROCESS_MOVE_ITERATOR_HPP_INCLUDED
Modified: trunk/boost/interprocess/detail/mpl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/mpl.hpp (original)
+++ trunk/boost/interprocess/detail/mpl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -59,6 +59,9 @@
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
+template <class Cond, class T = void>
+struct disable_if : public enable_if_c<!Cond::value, T> {};
+
template <class T, class U>
class is_convertible
{
@@ -105,7 +108,8 @@
struct select1st
// : public std::unary_function<Pair, typename Pair::first_type>
{
- const typename Pair::first_type& operator()(const Pair& x) const
+ template<class OtherPair>
+ const typename Pair::first_type& operator()(const OtherPair& x) const
{ return x.first; }
const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
Modified: trunk/boost/interprocess/detail/named_proxy.hpp
==============================================================================
--- trunk/boost/interprocess/detail/named_proxy.hpp (original)
+++ trunk/boost/interprocess/detail/named_proxy.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -72,11 +72,11 @@
private:
template<int ...IdxPack>
void construct(void *mem, detail::true_, const index_tuple<IdxPack...>&)
- { new((void*)mem)T(*detail::forward_impl<Args>(get<IdxPack>(args_))...); }
+ { new((void*)mem)T(*boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
template<int ...IdxPack>
void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&)
- { new((void*)mem)T(detail::forward_impl<Args>(get<IdxPack>(args_))...); }
+ { new((void*)mem)T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
template<int ...IdxPack>
void do_increment(detail::true_, const index_tuple<IdxPack...>&)
@@ -120,7 +120,7 @@
template<class ...Args>
T *operator()(Args &&...args) const
{
- CtorNArg<T, is_iterator, Args...> ctor_obj(detail::forward_impl<Args>(args)...);
+ CtorNArg<T, is_iterator, Args...> ctor_obj(boost::interprocess::forward<Args>(args)...);
return mp_mngr->template
generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
}
@@ -211,7 +211,7 @@
//be able to bind temporaries. After that we will un-const them.
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
-//bind rvalues with non-const references, we have to be ugly
+//bind lvalues with non-const references, we have to be ugly
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T, bool is_iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
Modified: trunk/boost/interprocess/detail/os_file_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_file_functions.hpp (original)
+++ trunk/boost/interprocess/detail/os_file_functions.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -13,9 +13,9 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-//#include <boost/interprocess/detail/utilities.hpp>
+#include <string>
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
@@ -35,11 +35,11 @@
namespace boost {
namespace interprocess {
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
typedef void * file_handle_t;
typedef long long offset_t;
-typedef struct{
+typedef struct mapping_handle_impl_t{
void * handle;
bool is_shm;
} mapping_handle_t;
@@ -65,6 +65,14 @@
return ret;
}
+inline mapping_handle_t mapping_handle_from_shm_handle(file_handle_t hnd)
+{
+ mapping_handle_t ret;
+ ret.handle = hnd;
+ ret.is_shm = true;
+ return ret;
+}
+
inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
{ return hnd.handle; }
@@ -99,10 +107,7 @@
}
inline bool delete_file(const char *name)
-{ return winapi::delete_file(name); }
-
-inline bool delete_file_on_reboot_if_possible(const char *filename)
-{ return winapi::move_file_ex(filename, 0, winapi::movefile_delay_until_reboot); }
+{ return winapi::unlink_file(name); }
inline bool truncate_file (file_handle_t hnd, std::size_t size)
{
@@ -191,16 +196,89 @@
return (acquired = true);
}
-
-
inline bool release_file_lock_sharable(file_handle_t hnd)
{ return release_file_lock(hnd); }
-#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+inline bool delete_subdirectories_recursive
+ (const std::string &refcstrRootDirectory, const char *dont_delete_this, unsigned int count)
+{
+ bool bSubdirectory = false; // Flag, indicating whether
+ // subdirectories have been found
+ void * hFile; // Handle to directory
+ std::string strFilePath; // Filepath
+ std::string strPattern; // Pattern
+ winapi::win32_find_data_t FileInformation; // File information
+
+ //Find all files and directories
+ strPattern = refcstrRootDirectory + "\\*.*";
+ hFile = winapi::find_first_file(strPattern.c_str(), &FileInformation);
+ if(hFile != winapi::invalid_handle_value){
+ do{
+ //If it's not "." or ".." or the pointed root_level dont_delete_this erase it
+ if(FileInformation.cFileName[0] != '.' &&
+ !(dont_delete_this && count == 0 && std::strcmp(dont_delete_this, FileInformation.cFileName) == 0)){
+ strFilePath.erase();
+ strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;
+
+ //If it's a directory, go recursive
+ if(FileInformation.dwFileAttributes & winapi::file_attribute_directory){
+ // Delete subdirectory
+ if(!delete_subdirectories_recursive(strFilePath, dont_delete_this, count+1))
+ return false;
+ }
+ //If it's a file, just delete it
+ else{
+ // Set file attributes
+ //if(::SetFileAttributes(strFilePath.c_str(), winapi::file_attribute_normal) == 0)
+ //return winapi::get_last_error();
+ // Delete file
+ if(winapi::delete_file(strFilePath.c_str()) == 0)
+ return false;
+ }
+ }
+ //Go to the next file
+ } while(winapi::find_next_file(hFile, &FileInformation) == 1);
+
+ // Close handle
+ winapi::find_close(hFile);
+
+ //See if the loop has ended with an error or just because we've traversed all the files
+ if(winapi::get_last_error() != winapi::error_no_more_files){
+ return false;
+ }
+ else
+ {
+ //Erase empty subdirectories or original refcstrRootDirectory
+ if(!bSubdirectory && count)
+ {
+ // Set directory attributes
+ //if(::SetFileAttributes(refcstrRootDirectory.c_str(), FILE_ATTRIBUTE_NORMAL) == 0)
+ //return ::GetLastError();
+ // Delete directory
+ if(winapi::remove_directory(refcstrRootDirectory.c_str()) == 0)
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+//This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
+inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
+{
+ return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this, 0u);
+}
+
+#else //#if (defined BOOST_INTERPROCESS_WINDOWS)
typedef int file_handle_t;
typedef off_t offset_t;
-typedef file_handle_t mapping_handle_t;
+
+typedef struct mapping_handle_impl_t
+{
+ file_handle_t handle;
+ bool is_xsi;
+} mapping_handle_t;
typedef enum { read_only = O_RDONLY
, read_write = O_RDWR
@@ -216,10 +294,15 @@
namespace detail{
inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
-{ return hnd; }
+{
+ mapping_handle_t ret;
+ ret.handle = hnd;
+ ret.is_xsi = false;
+ return ret;
+}
inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
-{ return hnd; }
+{ return hnd.handle; }
inline bool create_directory(const char *path)
{ return ::mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; }
@@ -263,12 +346,6 @@
inline bool delete_file(const char *name)
{ return ::unlink(name) == 0; }
-
-inline bool delete_file_on_reboot_if_possible(const char *)
-{ //Function not implemented in POSIX functions
- return false;
-}
-
inline bool truncate_file (file_handle_t hnd, std::size_t size)
{ return 0 == ::ftruncate(hnd, size); }
@@ -365,7 +442,7 @@
inline bool release_file_lock_sharable(file_handle_t hnd)
{ return release_file_lock(hnd); }
-#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
} //namespace detail{
} //namespace interprocess {
Modified: trunk/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_thread_functions.hpp (original)
+++ trunk/boost/interprocess/detail/os_thread_functions.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -14,7 +14,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
@@ -30,7 +30,7 @@
namespace interprocess {
namespace detail{
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
typedef unsigned long OS_process_id_t;
typedef unsigned long OS_thread_id_t;
@@ -40,6 +40,9 @@
inline OS_process_id_t get_current_process_id()
{ return winapi::get_current_process_id(); }
+inline OS_process_id_t get_invalid_process_id()
+{ return OS_process_id_t(0); }
+
//thread
inline OS_thread_id_t get_current_thread_id()
{ return winapi::get_current_thread_id(); }
@@ -59,6 +62,12 @@
return get_current_thread_id();
}
+inline void systemwide_thread_id_copy
+ (const volatile OS_systemwide_thread_id_t &from, volatile OS_systemwide_thread_id_t &to)
+{
+ to = from;
+}
+
inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
{
return equal_thread_id(id1, id2);
@@ -69,24 +78,56 @@
return get_invalid_thread_id();
}
-#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#else //#if (defined BOOST_INTERPROCESS_WINDOWS)
typedef pthread_t OS_thread_id_t;
typedef pid_t OS_process_id_t;
struct OS_systemwide_thread_id_t
{
+ OS_systemwide_thread_id_t()
+ : pid(), tid()
+ {}
+
OS_systemwide_thread_id_t(pid_t p, pthread_t t)
: pid(p), tid(t)
{}
+
+ OS_systemwide_thread_id_t(const OS_systemwide_thread_id_t &x)
+ : pid(x.pid), tid(x.tid)
+ {}
+
+ OS_systemwide_thread_id_t(const volatile OS_systemwide_thread_id_t &x)
+ : pid(x.pid), tid(x.tid)
+ {}
+
+ OS_systemwide_thread_id_t & operator=(const OS_systemwide_thread_id_t &x)
+ { pid = x.pid; tid = x.tid; return *this; }
+
+ OS_systemwide_thread_id_t & operator=(const volatile OS_systemwide_thread_id_t &x)
+ { pid = x.pid; tid = x.tid; return *this; }
+
+ void operator=(const OS_systemwide_thread_id_t &x) volatile
+ { pid = x.pid; tid = x.tid; }
+
pid_t pid;
pthread_t tid;
};
+inline void systemwide_thread_id_copy
+ (const volatile OS_systemwide_thread_id_t &from, volatile OS_systemwide_thread_id_t &to)
+{
+ to.pid = from.pid;
+ to.tid = from.tid;
+}
+
//process
inline OS_process_id_t get_current_process_id()
{ return ::getpid(); }
+inline OS_process_id_t get_invalid_process_id()
+{ return pid_t(0); }
+
//thread
inline OS_thread_id_t get_current_thread_id()
{ return ::pthread_self(); }
@@ -116,10 +157,10 @@
inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
{
- return OS_systemwide_thread_id_t(pid_t(0), get_invalid_thread_id());
+ return OS_systemwide_thread_id_t(get_invalid_process_id(), get_invalid_thread_id());
}
-#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
} //namespace detail{
} //namespace interprocess {
Modified: trunk/boost/interprocess/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/interprocess/detail/preprocessor.hpp (original)
+++ trunk/boost/interprocess/detail/preprocessor.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -36,7 +36,7 @@
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind rvalues with non-const references, we have to be ugly
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_INTERPROCESS_PP_PARAM_LIST(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
//!
@@ -46,7 +46,7 @@
//!
#endif
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_INTERPROCESS_PARAM(U, u) \
U && u \
//!
@@ -56,7 +56,7 @@
//!
#endif
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
//!
@@ -70,7 +70,7 @@
BOOST_PP_CAT(++m_p, n) \
//!
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#ifdef BOOST_HAS_RVALUE_REFS
#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
//!
@@ -80,25 +80,13 @@
//!
#endif
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- #define BOOST_INTERPROCESS_PP_PARAM_FORWARD(z, n, data) \
- detail::forward_impl< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
- //!
-#else
- #define BOOST_INTERPROCESS_PP_PARAM_FORWARD(z, n, data) \
- BOOST_PP_CAT(p, n) \
- //!
-#endif
+#define BOOST_INTERPROCESS_PP_PARAM_FORWARD(z, n, data) \
+boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+//!
-#ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- #define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
- detail::forward_impl< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
- //!
-#else
- #define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
- BOOST_PP_CAT(m_p, n) \
- //!
-#endif
+#define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
+boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
+//!
#define BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD(z, n, data) \
BOOST_PP_CAT(*m_p, n) \
Modified: trunk/boost/interprocess/detail/segment_manager_helper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/segment_manager_helper.hpp (original)
+++ trunk/boost/interprocess/detail/segment_manager_helper.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,6 +18,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -27,6 +29,8 @@
#include <string> //char_traits
#include <new> //std::nothrow
#include <utility> //std::pair
+#include <cassert> //assert
+#include <functional> //unary_function
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#endif
@@ -75,7 +79,7 @@
block_header(std::size_t value_bytes
,std::size_t value_alignment
- ,std::size_t allocation_type
+ ,std::size_t alloc_type
,std::size_t sizeof_char
,std::size_t num_char
)
@@ -83,7 +87,7 @@
, m_num_char(num_char)
, m_value_alignment(value_alignment)
, m_alloc_type_sizeof_char
- ( ((unsigned char)allocation_type << 5u) |
+ ( ((unsigned char)alloc_type << 5u) |
((unsigned char)sizeof_char & 0x1F) )
{};
@@ -94,7 +98,7 @@
std::size_t total_size() const
{
- if(allocation_type() != anonymous_type){
+ if(alloc_type() != anonymous_type){
return name_offset() + (m_num_char+1)*sizeof_char();
}
else{
@@ -114,7 +118,7 @@
+ total_size();
}
- std::size_t allocation_type() const
+ std::size_t alloc_type() const
{ return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
std::size_t sizeof_char() const
@@ -252,6 +256,7 @@
typedef instance_t<anonymous_type> anonymous_instance_t;
typedef instance_t<unique_type> unique_instance_t;
+
template<class Hook, class CharType>
struct intrusive_value_type_impl
: public Hook
@@ -325,7 +330,7 @@
template<class CharT, class VoidPointer>
struct index_key
{
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<VoidPointer, const CharT>::type const_char_ptr_t;
typedef CharT char_type;
@@ -471,6 +476,26 @@
} //namespace detail {
+//These pointers are the ones the user will use to
+//indicate previous allocation types
+static const detail::anonymous_instance_t * anonymous_instance = 0;
+static const detail::unique_instance_t * unique_instance = 0;
+
+namespace detail_really_deep_namespace {
+
+//Otherwise, gcc issues a warning of previously defined
+//anonymous_instance and unique_instance
+struct dummy
+{
+ dummy()
+ {
+ (void)anonymous_instance;
+ (void)unique_instance;
+ }
+};
+
+} //detail_really_deep_namespace
+
}} //namespace boost { namespace interprocess
#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/boost/interprocess/detail/tmp_dir_helpers.hpp
==============================================================================
--- trunk/boost/interprocess/detail/tmp_dir_helpers.hpp (original)
+++ trunk/boost/interprocess/detail/tmp_dir_helpers.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,10 +18,87 @@
#include <boost/interprocess/exceptions.hpp>
#include <string>
+#if (defined BOOST_INTERPROCESS_WINDOWS)
+# include <boost/interprocess/detail/win32_api.hpp>
+#endif
+
namespace boost {
namespace interprocess {
namespace detail {
+#if (defined BOOST_INTERPROCESS_WINDOWS)
+
+inline void tmp_filename(const char *filename, std::string &tmp_name)
+{
+ const char *tmp_dir = get_temporary_path();
+ if(!tmp_dir){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ tmp_name = tmp_dir;
+
+ //Remove final null.
+ tmp_name += "/boost_interprocess/";
+
+ char bootstamp[winapi::BootstampLength*2+1];
+ std::size_t bootstamp_length = winapi::BootstampLength*2;
+ winapi::get_boot_time_str(bootstamp, bootstamp_length);
+ bootstamp[winapi::BootstampLength*2] = 0;
+ tmp_name += bootstamp;
+ tmp_name += '/';
+ tmp_name += filename;
+}
+
+inline void create_tmp_dir_and_get_filename(const char *filename, std::string &tmp_name)
+{
+ //First get the temp directory
+ const char *tmp_path = get_temporary_path();
+ if(!tmp_path){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+
+ //Create Boost.Interprocess dir
+ tmp_name = tmp_path;
+ tmp_name += "/boost_interprocess";
+
+ //If fails, check that it's because already exists
+ if(!create_directory(tmp_name.c_str())){
+ error_info info(system_error_code());
+ if(info.get_error_code() != already_exists_error){
+ throw interprocess_exception(info);
+ }
+ }
+
+ //Obtain bootstamp string
+ char bootstamp[winapi::BootstampLength*2+1];
+ std::size_t bootstamp_length = winapi::BootstampLength*2;
+ winapi::get_boot_time_str(bootstamp, bootstamp_length);
+ bootstamp[winapi::BootstampLength*2] = 0;
+
+ //Create a new subdirectory with the bootstamp
+ std::string root_tmp_name = tmp_name;
+ tmp_name += '/';
+ tmp_name += bootstamp;
+
+ //If fails, check that it's because already exists
+ if(!create_directory(tmp_name.c_str())){
+ error_info info(system_error_code());
+ if(info.get_error_code() != already_exists_error){
+ throw interprocess_exception(info);
+ }
+ }
+
+ //Now erase all old directories created in the previous boot sessions
+ delete_subdirectories(root_tmp_name, bootstamp);
+
+ //Add filename
+ tmp_name += '/';
+ tmp_name += filename;
+}
+
+#else //POSIX SYSTEMS
+
inline void tmp_filename(const char *filename, std::string &tmp_name)
{
const char *tmp_dir = get_temporary_path();
@@ -61,6 +138,8 @@
tmp_name += filename;
}
+#endif
+
inline void add_leading_slash(const char *name, std::string &new_name)
{
if(name[0] != '/'){
Added: trunk/boost/interprocess/detail/transform_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/transform_iterator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,180 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_TRANSFORM_ITERATORS_HPP
+#define BOOST_INTERPROCESS_DETAIL_TRANSFORM_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/interprocess_fwd.hpp>
+
+#include <iterator>
+#include <boost/interprocess/detail/type_traits.hpp>
+
+namespace boost {
+namespace interprocess {
+
+template <class PseudoReference>
+struct operator_arrow_proxy
+{
+ operator_arrow_proxy(const PseudoReference &px)
+ : m_value(px)
+ {}
+
+ PseudoReference* operator->() const { return &m_value; }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+// operator T*() const { return &m_value; }
+ mutable PseudoReference m_value;
+};
+
+template <class T>
+struct operator_arrow_proxy<T&>
+{
+ operator_arrow_proxy(T &px)
+ : m_value(px)
+ {}
+
+ T* operator->() const { return &m_value; }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+// operator T*() const { return &m_value; }
+ mutable T &m_value;
+};
+
+template <class Iterator, class UnaryFunction>
+class transform_iterator
+ : public UnaryFunction
+ , public std::iterator
+ < typename Iterator::iterator_category
+ , typename detail::remove_reference<typename UnaryFunction::result_type>::type
+ , typename Iterator::difference_type
+ , operator_arrow_proxy<typename UnaryFunction::result_type>
+ , typename UnaryFunction::result_type>
+{
+ public:
+ explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
+ : UnaryFunction(f), m_it(it)
+ {}
+
+ explicit transform_iterator()
+ : UnaryFunction(), m_it()
+ {}
+
+ //Constructors
+ transform_iterator& operator++()
+ { increment(); return *this; }
+
+ transform_iterator operator++(int)
+ {
+ transform_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i == i2); }
+
+/*
+ friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i < i2); }
+*/
+ friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ transform_iterator& operator+=(typename Iterator::difference_type off)
+ { this->advance(off); return *this; }
+
+ transform_iterator operator+(typename Iterator::difference_type off) const
+ {
+ transform_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
+ { return right + off; }
+
+ transform_iterator& operator-=(typename Iterator::difference_type off)
+ { this->advance(-off); return *this; }
+
+ transform_iterator operator-(typename Iterator::difference_type off) const
+ { return *this + (-off); }
+
+ typename UnaryFunction::result_type operator*() const
+ { return dereference(); }
+
+ operator_arrow_proxy<typename UnaryFunction::result_type>
+ operator->() const
+ { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
+
+ Iterator & base()
+ { return m_it; }
+
+ const Iterator & base() const
+ { return m_it; }
+
+ private:
+ Iterator m_it;
+
+ void increment()
+ { ++m_it; }
+
+ void decrement()
+ { --m_it; }
+
+ bool equal(const transform_iterator &other) const
+ { return m_it == other.m_it; }
+
+ bool less(const transform_iterator &other) const
+ { return other.m_it < m_it; }
+
+ typename UnaryFunction::result_type dereference() const
+ { return UnaryFunction::operator()(*m_it); }
+
+ void advance(typename Iterator::difference_type n)
+ { std::advance(m_it, n); }
+
+ typename Iterator::difference_type distance_to(const transform_iterator &other)const
+ { return std::distance(other.m_it, m_it); }
+};
+
+template <class Iterator, class UnaryFunc>
+transform_iterator<Iterator, UnaryFunc>
+make_transform_iterator(Iterator it, UnaryFunc fun)
+{
+ return transform_iterator<Iterator, UnaryFunc>(it, fun);
+}
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_DETAIL_TRANSFORM_ITERATORS_HPP
+
Modified: trunk/boost/interprocess/detail/type_traits.hpp
==============================================================================
--- trunk/boost/interprocess/detail/type_traits.hpp (original)
+++ trunk/boost/interprocess/detail/type_traits.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -120,13 +120,13 @@
template<>
struct add_reference<void>
{
- typedef nat& type;
+ typedef nat &type;
};
template<>
struct add_reference<const void>
{
- typedef const nat& type;
+ typedef const nat &type;
};
template <class T>
Modified: trunk/boost/interprocess/detail/utilities.hpp
==============================================================================
--- trunk/boost/interprocess/detail/utilities.hpp (original)
+++ trunk/boost/interprocess/detail/utilities.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -26,11 +26,10 @@
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/interprocess/detail/min_max.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
-#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-#include <boost/interprocess/detail/preprocessor.hpp>
-#endif
+#include <boost/interprocess/detail/transform_iterator.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
+#include <boost/interprocess/detail/move.hpp>
#include <utility>
#include <algorithm>
@@ -70,321 +69,6 @@
swap(x, y);
}
-//!A deleter for scoped_ptr that deallocates the memory
-//!allocated for an object using a STL allocator.
-template <class Allocator>
-struct scoped_ptr_dealloc_functor
-{
- typedef typename Allocator::pointer pointer;
- typedef detail::integral_constant<unsigned,
- boost::interprocess::detail::
- version<Allocator>::value> alloc_version;
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
-
- private:
- void priv_deallocate(const typename Allocator::pointer &p, allocator_v1)
- { m_alloc.deallocate(p, 1); }
-
- void priv_deallocate(const typename Allocator::pointer &p, allocator_v2)
- { m_alloc.deallocate_one(p); }
-
- public:
- Allocator& m_alloc;
-
- scoped_ptr_dealloc_functor(Allocator& a)
- : m_alloc(a) {}
-
- void operator()(pointer ptr)
- { if (ptr) priv_deallocate(ptr, alloc_version()); }
-};
-
-//!A deleter for scoped_ptr that deallocates the memory
-//!allocated for an object using a STL allocator.
-template <class Allocator>
-struct scoped_deallocator
-{
- typedef typename Allocator::pointer pointer;
- typedef detail::integral_constant<unsigned,
- boost::interprocess::detail::
- version<Allocator>::value> alloc_version;
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
-
- private:
- void priv_deallocate(allocator_v1)
- { m_alloc.deallocate(m_ptr, 1); }
-
- void priv_deallocate(allocator_v2)
- { m_alloc.deallocate_one(m_ptr); }
-
- scoped_deallocator(const scoped_deallocator &);
- scoped_deallocator& operator=(const scoped_deallocator &);
-
- public:
- pointer m_ptr;
- Allocator& m_alloc;
-
- scoped_deallocator(pointer p, Allocator& a)
- : m_ptr(p), m_alloc(a) {}
-
- ~scoped_deallocator()
- { if (m_ptr)priv_deallocate(alloc_version()); }
-
- #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- scoped_deallocator(scoped_deallocator &&o)
- : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
- {
- #else
- scoped_deallocator(moved_object<scoped_deallocator> mo)
- : m_ptr(mo.get().m_ptr), m_alloc(mo.get().m_alloc)
- {
- scoped_deallocator &o = mo.get();
- #endif
- o.release();
- }
-
- pointer get() const
- { return m_ptr; }
-
- void release()
- { m_ptr = 0; }
-};
-
-} //namespace detail {
-
-template <class Allocator>
-struct is_movable<boost::interprocess::detail::scoped_deallocator<Allocator> >
-{
- static const bool value = true;
-};
-
-namespace detail {
-
-//!A deleter for scoped_ptr that deallocates the memory
-//!allocated for an array of objects using a STL allocator.
-template <class Allocator>
-struct scoped_array_deallocator
-{
- typedef typename Allocator::pointer pointer;
- typedef typename Allocator::size_type size_type;
-
- scoped_array_deallocator(pointer p, Allocator& a, size_type length)
- : m_ptr(p), m_alloc(a), m_length(length) {}
-
- ~scoped_array_deallocator()
- { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
-
- void release()
- { m_ptr = 0; }
-
- private:
- pointer m_ptr;
- Allocator& m_alloc;
- size_type m_length;
-};
-
-template <class Allocator>
-struct null_scoped_array_deallocator
-{
- typedef typename Allocator::pointer pointer;
- typedef typename Allocator::size_type size_type;
-
- null_scoped_array_deallocator(pointer, Allocator&, size_type)
- {}
-
- void release()
- {}
-};
-
-//!A deleter for scoped_ptr that destroys
-//!an object using a STL allocator.
-template <class Allocator>
-struct scoped_destructor_n
-{
- typedef typename Allocator::pointer pointer;
- typedef typename Allocator::value_type value_type;
- typedef typename Allocator::size_type size_type;
-
- pointer m_p;
- size_type m_n;
-
- scoped_destructor_n(pointer p, size_type n)
- : m_p(p), m_n(n)
- {}
-
- void release()
- { m_p = 0; }
-
- void increment_size(size_type inc)
- { m_n += inc; }
-
- ~scoped_destructor_n()
- {
- if(!m_p) return;
- value_type *raw_ptr = detail::get_pointer(m_p);
- for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr)
- raw_ptr->~value_type();
- }
-};
-
-//!A deleter for scoped_ptr that destroys
-//!an object using a STL allocator.
-template <class Allocator>
-struct null_scoped_destructor_n
-{
- typedef typename Allocator::pointer pointer;
- typedef typename Allocator::size_type size_type;
-
- null_scoped_destructor_n(pointer, size_type)
- {}
-
- void increment_size(size_type)
- {}
-
- void release()
- {}
-};
-
-template <class A>
-class allocator_destroyer
-{
- typedef typename A::value_type value_type;
- typedef detail::integral_constant<unsigned,
- boost::interprocess::detail::
- version<A>::value> alloc_version;
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
-
- private:
- A & a_;
-
- private:
- void priv_deallocate(const typename A::pointer &p, allocator_v1)
- { a_.deallocate(p, 1); }
-
- void priv_deallocate(const typename A::pointer &p, allocator_v2)
- { a_.deallocate_one(p); }
-
- public:
- allocator_destroyer(A &a)
- : a_(a)
- {}
-
- void operator()(const typename A::pointer &p)
- {
- detail::get_pointer(p)->~value_type();
- priv_deallocate(p, alloc_version());
- }
-};
-
-template <class A>
-class allocator_destroyer_and_chain_builder
-{
- typedef typename A::value_type value_type;
- typedef typename A::multiallocation_iterator multiallocation_iterator;
- typedef typename A::multiallocation_chain multiallocation_chain;
-
- A & a_;
- multiallocation_chain &c_;
-
- public:
- allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
- : a_(a), c_(c)
- {}
-
- void operator()(const typename A::pointer &p)
- {
- value_type *vp = detail::get_pointer(p);
- vp->~value_type();
- c_.push_back(vp);
- }
-};
-
-template <class A>
-class allocator_multialloc_chain_node_deallocator
-{
- typedef typename A::value_type value_type;
- typedef typename A::multiallocation_iterator multiallocation_iterator;
- typedef typename A::multiallocation_chain multiallocation_chain;
- typedef allocator_destroyer_and_chain_builder<A> chain_builder;
-
- A & a_;
- multiallocation_chain c_;
-
- public:
- allocator_multialloc_chain_node_deallocator(A &a)
- : a_(a), c_()
- {}
-
- chain_builder get_chain_builder()
- { return chain_builder(a_, c_); }
-
- ~allocator_multialloc_chain_node_deallocator()
- {
- multiallocation_iterator it(c_.get_it());
- if(it != multiallocation_iterator())
- a_.deallocate_individual(it);
- }
-};
-
-template <class A>
-class allocator_multialloc_chain_array_deallocator
-{
- typedef typename A::value_type value_type;
- typedef typename A::multiallocation_iterator multiallocation_iterator;
- typedef typename A::multiallocation_chain multiallocation_chain;
- typedef allocator_destroyer_and_chain_builder<A> chain_builder;
-
- A & a_;
- multiallocation_chain c_;
-
- public:
- allocator_multialloc_chain_array_deallocator(A &a)
- : a_(a), c_()
- {}
-
- chain_builder get_chain_builder()
- { return chain_builder(a_, c_); }
-
- ~allocator_multialloc_chain_array_deallocator()
- {
- multiallocation_iterator it(c_.get_it());
- if(it != multiallocation_iterator())
- a_.deallocate_many(it);
- }
-};
-
-//!A class used for exception-safe multi-allocation + construction.
-template <class Allocator>
-struct multiallocation_destroy_dealloc
-{
- typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
- typedef typename Allocator::value_type value_type;
-
- multiallocation_iterator m_itbeg;
- Allocator& m_alloc;
-
- multiallocation_destroy_dealloc(multiallocation_iterator itbeg, Allocator& a)
- : m_itbeg(itbeg), m_alloc(a) {}
-
- ~multiallocation_destroy_dealloc()
- {
- multiallocation_iterator endit;
- while(m_itbeg != endit){
- detail::get_pointer(&*m_itbeg)->~value_type();
- m_alloc.deallocate(&*m_itbeg, 1);
- ++m_itbeg;
- }
- }
-
- void next()
- { ++m_itbeg; }
-
- void release()
- { m_itbeg = multiallocation_iterator(); }
-};
-
//Rounds "orig_size" by excess to round_to bytes
inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
{
@@ -415,18 +99,6 @@
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
};
-template <std::size_t Value1, std::size_t Value2>
-struct ct_min
-{
- enum { value = (Value1 < Value2)? Value1 : Value2 };
-};
-
-template <std::size_t Value1, std::size_t Value2>
-struct ct_max
-{
- enum { value = (Value1 > Value2)? Value1 : Value2 };
-};
-
// Gennaro Prota wrote this. Thanks!
template <int p, int n = 4>
struct ct_max_pow2_less
@@ -443,38 +115,6 @@
static const std::size_t value = 0;
};
-//!Obtains a generic pointer of the same type that
-//!can point to other pointed type: Ptr<?> -> Ptr<NewValueType>
-template<class T, class U>
-struct pointer_to_other;
-
-template<class T, class U,
- template<class> class Sp>
-struct pointer_to_other< Sp<T>, U >
-{
- typedef Sp<U> type;
-};
-
-template<class T, class T2, class U,
- template<class, class> class Sp>
-struct pointer_to_other< Sp<T, T2>, U >
-{
- typedef Sp<U, T2> type;
-};
-
-template<class T, class T2, class T3, class U,
- template<class, class, class> class Sp>
-struct pointer_to_other< Sp<T, T2, T3>, U >
-{
- typedef Sp<U, T2, T3> type;
-};
-
-template<class T, class U>
-struct pointer_to_other< T*, U >
-{
- typedef U* type;
-};
-
} //namespace detail {
//!Trait class to detect if an index is a node
@@ -486,7 +126,6 @@
enum { value = false };
};
-
//!Trait class to detect if an index is an intrusive
//!index. This will embed the derivation hook in each
//!allocation header, to provide memory for the intrusive
@@ -497,334 +136,6 @@
enum { value = false };
};
-template <class SizeType>
-SizeType
- get_next_capacity(const SizeType max_size
- ,const SizeType capacity
- ,const SizeType n)
-{
-// if (n > max_size - capacity)
-// throw std::length_error("get_next_capacity");
-
- const SizeType m3 = max_size/3;
-
- if (capacity < m3)
- return capacity + max_value(3*(capacity+1)/5, n);
-
- if (capacity < m3*2)
- return capacity + max_value((capacity+1)/2, n);
-
- return max_size;
-}
-
-namespace detail {
-
-template <class T1, class T2>
-struct pair
-{
- typedef T1 first_type;
- typedef T2 second_type;
-
- T1 first;
- T2 second;
-
- //std::pair compatibility
- template <class D, class S>
- pair(const std::pair<D, S>& p)
- : first(p.first), second(p.second)
- {}
-
- //To resolve ambiguity with the variadic constructor of 1 argument
- //and the previous constructor
- pair(std::pair<T1, T2>& x)
- : first(x.first), second(x.second)
- {}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template <class D, class S>
- pair(detail::moved_object<std::pair<D, S> > p)
- : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
- {}
- #else
- template <class D, class S>
- pair(std::pair<D, S> && p)
- : first(detail::move_impl(p.first)), second(detail::move_impl(p.second))
- {}
- #endif
-
- pair()
- : first(), second()
- {}
-
- pair(const pair<T1, T2>& x)
- : first(x.first), second(x.second)
- {}
-
- //To resolve ambiguity with the variadic constructor of 1 argument
- //and the copy constructor
- pair(pair<T1, T2>& x)
- : first(x.first), second(x.second)
- {}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair(detail::moved_object<pair<T1, T2> > p)
- : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
- {}
- #else
- pair(pair<T1, T2> && p)
- : first(detail::move_impl(p.first)), second(detail::move_impl(p.second))
- {}
- #endif
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template <class D, class S>
- pair(detail::moved_object<pair<D, S> > p)
- : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
- {}
- #else
- template <class D, class S>
- pair(pair<D, S> && p)
- : first(detail::move_impl(p.first)), second(detail::move_impl(p.second))
- {}
- #endif
-
- #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-
- template<class U, class ...Args>
- pair(U &&u, Args &&... args)
- : first(detail::forward_impl<U>(u))
- , second(detail::forward_impl<Args>(args)...)
- {}
-
- #else
-
- template<class U>
- pair(BOOST_INTERPROCESS_PARAM(U, u))
- : first(detail::forward_impl<U>(u))
- {}
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
- pair(BOOST_INTERPROCESS_PARAM(U, u) \
- ,BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
- : first(detail::forward_impl<U>(u)) \
- , second(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
- #endif
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair& operator=(detail::moved_object<pair<T1, T2> > p)
- {
- first = detail::move_impl(p.get().first);
- second = detail::move_impl(p.get().second);
- return *this;
- }
- #else
- pair& operator=(pair<T1, T2> &&p)
- {
- first = detail::move_impl(p.first);
- second = detail::move_impl(p.second);
- return *this;
- }
- #endif
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair& operator=(detail::moved_object<std::pair<T1, T2> > p)
- {
- first = detail::move_impl(p.get().first);
- second = detail::move_impl(p.get().second);
- return *this;
- }
- #else
- pair& operator=(std::pair<T1, T2> &&p)
- {
- first = detail::move_impl(p.first);
- second = detail::move_impl(p.second);
- return *this;
- }
- #endif
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template <class D, class S>
- pair& operator=(detail::moved_object<std::pair<D, S> > p)
- {
- first = detail::move_impl(p.get().first);
- second = detail::move_impl(p.get().second);
- return *this;
- }
- #else
- template <class D, class S>
- pair& operator=(std::pair<D, S> &&p)
- {
- first = detail::move_impl(p.first);
- second = detail::move_impl(p.second);
- return *this;
- }
- #endif
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(detail::moved_object<pair> p)
- { std::swap(*this, p.get()); }
-
- void swap(pair& p)
- { std::swap(*this, p); }
-
- #else
- void swap(pair &&p)
- { std::swap(*this, p); }
- #endif
-};
-
-template <class T1, class T2>
-inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
-{ return static_cast<bool>(x.first == y.first && x.second == y.second); }
-
-template <class T1, class T2>
-inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
-{ return static_cast<bool>(x.first < y.first ||
- (!(y.first < x.first) && x.second < y.second)); }
-
-template <class T1, class T2>
-inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
-{ return static_cast<bool>(!(x == y)); }
-
-template <class T1, class T2>
-inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
-{ return y < x; }
-
-template <class T1, class T2>
-inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
-{ return static_cast<bool>(!(x < y)); }
-
-template <class T1, class T2>
-inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
-{ return static_cast<bool>(!(y < x)); }
-
-template <class T1, class T2>
-inline pair<T1, T2> make_pair(T1 x, T2 y)
-{ return pair<T1, T2>(x, y); }
-
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-template <class T1, class T2>
-inline void swap(detail::moved_object<pair<T1, T2> > &x, pair<T1, T2> y)
-{
- swap(x.get().first, y.first);
- swap(x.get().second, y.second);
-}
-
-template <class T1, class T2>
-inline void swap(pair<T1, T2>& x, detail::moved_object<pair<T1, T2> > y)
-{
- swap(x.first, y.get().first);
- swap(x.second, y.get().second);
-}
-
-template <class T1, class T2>
-inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
-{
- swap(x.first, y.first);
- swap(x.second, y.second);
-}
-
-#else
-template <class T1, class T2>
-inline void swap(pair<T1, T2>&&x, pair<T1, T2>&&y)
-{
- swap(x.first, y.first);
- swap(x.second, y.second);
-}
-#endif
-
-template<class T>
-struct cast_functor
-{
- typedef typename detail::add_reference<T>::type result_type;
- result_type operator()(char &ptr) const
- { return *static_cast<T*>(static_cast<void*>(&ptr)); }
-};
-
-template<class MultiallocChain, class T>
-class multiallocation_chain_adaptor
-{
- private:
- MultiallocChain chain_;
-
- multiallocation_chain_adaptor
- (const multiallocation_chain_adaptor &);
- multiallocation_chain_adaptor &operator=
- (const multiallocation_chain_adaptor &);
-
- public:
- typedef transform_iterator
- < typename MultiallocChain::
- multiallocation_iterator
- , detail::cast_functor <T> > multiallocation_iterator;
-
- multiallocation_chain_adaptor()
- : chain_()
- {}
-
- void push_back(T *mem)
- { chain_.push_back(mem); }
-
- void push_front(T *mem)
- { chain_.push_front(mem); }
-
- void swap(multiallocation_chain_adaptor &other_chain)
- { chain_.swap(other_chain.chain_); }
-
- void splice_back(multiallocation_chain_adaptor &other_chain)
- { chain_.splice_back(other_chain.chain_); }
-
- T *pop_front()
- { return static_cast<T*>(chain_.pop_front()); }
-
- bool empty() const
- { return chain_.empty(); }
-
- multiallocation_iterator get_it() const
- { return multiallocation_iterator(chain_.get_it()); }
-
- std::size_t size() const
- { return chain_.size(); }
-};
-
-template<class T>
-struct value_init
-{
- value_init()
- : m_t()
- {}
-
- T m_t;
-};
-
-} //namespace detail {
-
-//!The pair is movable if any of its members is movable
-template <class T1, class T2>
-struct is_movable<boost::interprocess::detail::pair<T1, T2> >
-{
- enum { value = is_movable<T1>::value || is_movable<T2>::value };
-};
-
-//!The pair is movable if any of its members is movable
-template <class T1, class T2>
-struct is_movable<std::pair<T1, T2> >
-{
- enum { value = is_movable<T1>::value || is_movable<T2>::value };
-};
-
-///has_trivial_destructor_after_move<> == true_type
-///specialization for optimizations
-template <class T>
-struct has_trivial_destructor_after_move
- : public boost::has_trivial_destructor<T>
-{};
-
template <typename T> T*
addressof(T& v)
{
@@ -850,36 +161,6 @@
bool m_erase;
};
-template <class T>
-struct sizeof_value
-{
- static const std::size_t value = sizeof(T);
-};
-
-template <>
-struct sizeof_value<void>
-{
- static const std::size_t value = sizeof(void*);
-};
-
-template <>
-struct sizeof_value<const void>
-{
- static const std::size_t value = sizeof(void*);
-};
-
-template <>
-struct sizeof_value<volatile void>
-{
- static const std::size_t value = sizeof(void*);
-};
-
-template <>
-struct sizeof_value<const volatile void>
-{
- static const std::size_t value = sizeof(void*);
-};
-
} //namespace interprocess {
} //namespace boost {
Deleted: trunk/boost/interprocess/detail/version_type.hpp
==============================================================================
--- trunk/boost/interprocess/detail/version_type.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,89 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-// This code comes from N1953 document by Howard E. Hinnant
-//
-//////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef BOOST_INTERPROCESS_DETAIL_VERSION_TYPE_HPP
-#define BOOST_INTERPROCESS_DETAIL_VERSION_TYPE_HPP
-
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/type_traits.hpp>
-
-
-namespace boost{
-namespace interprocess{
-namespace detail{
-
-//using namespace boost;
-
-template <class T, unsigned V>
-struct version_type
- : public detail::integral_constant<unsigned, V>
-{
- typedef T type;
-
- version_type(const version_type<T, 0>&);
-};
-
-namespace impl{
-
-template <class T,
- bool = detail::is_convertible<version_type<T, 0>, typename T::version>::value>
-struct extract_version
-{
- static const unsigned value = 1;
-};
-
-template <class T>
-struct extract_version<T, true>
-{
- static const unsigned value = T::version::value;
-};
-
-template <class T>
-struct has_version
-{
- private:
- struct two {char _[2];};
- template <class U> static two test(...);
- template <class U> static char test(const typename U::version*);
- public:
- static const bool value = sizeof(test<T>(0)) == 1;
- void dummy(){}
-};
-
-template <class T, bool = has_version<T>::value>
-struct version
-{
- static const unsigned value = 1;
-};
-
-template <class T>
-struct version<T, true>
-{
- static const unsigned value = extract_version<T>::value;
-};
-
-} //namespace impl
-
-template <class T>
-struct version
- : public detail::integral_constant<unsigned, impl::version<T>::value>
-{
-};
-
-} //namespace detail{
-} //namespace interprocess{
-} //namespace boost{
-
-#endif //#define BOOST_INTERPROCESS_DETAIL_VERSION_TYPE_HPP
Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp (original)
+++ trunk/boost/interprocess/detail/win32_api.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -14,13 +14,15 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <cstddef>
+#include <cstring>
+#include <memory>
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
# pragma comment( lib, "advapi32.lib" )
#endif
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
# include <cstdarg>
# include <boost/detail/interlocked.hpp>
#else
@@ -37,6 +39,7 @@
static const unsigned long infinite_time = 0xFFFFFFFF;
static const unsigned long error_already_exists = 183L;
static const unsigned long error_file_not_found = 2u;
+static const unsigned long error_no_more_files = 18u;
static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3;
static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001;
@@ -62,6 +65,15 @@
static const unsigned long file_map_write = section_map_write;
static const unsigned long file_map_read = section_map_read;
static const unsigned long file_map_all_access = section_all_access;
+static const unsigned long delete_access = 0x00010000L;
+static const unsigned long file_flag_backup_semantics = 0x02000000;
+static const long file_flag_delete_on_close = 0x04000000;
+
+//Native API constants
+static const unsigned long file_open_for_backup_intent = 0x00004000;
+static const int file_share_valid_flags = 0x00000007;
+static const long file_delete_on_close = 0x00001000L;
+static const long obj_case_insensitive = 0x00000040L;
static const unsigned long movefile_copy_allowed = 0x02;
static const unsigned long movefile_delay_until_reboot = 0x04;
@@ -74,6 +86,15 @@
static const unsigned long file_share_write = 0x00000002;
static const unsigned long file_share_delete = 0x00000004;
+static const unsigned long file_attribute_readonly = 0x00000001;
+static const unsigned long file_attribute_hidden = 0x00000002;
+static const unsigned long file_attribute_system = 0x00000004;
+static const unsigned long file_attribute_directory = 0x00000010;
+static const unsigned long file_attribute_archive = 0x00000020;
+static const unsigned long file_attribute_device = 0x00000040;
+static const unsigned long file_attribute_normal = 0x00000080;
+static const unsigned long file_attribute_temporary = 0x00000100;
+
static const unsigned long generic_read = 0x80000000L;
static const unsigned long generic_write = 0x40000000L;
@@ -109,8 +130,6 @@
static const unsigned long open_always = 4;
static const unsigned long truncate_existing = 5;
-static const unsigned long file_attribute_temporary = 0x00000100;
-
static const unsigned long file_begin = 0;
static const unsigned long file_current = 1;
static const unsigned long file_end = 2;
@@ -120,6 +139,13 @@
static const unsigned long error_lock_violation = 33;
static const unsigned long security_descriptor_revision = 1;
+//Own defines
+static const long SystemTimeOfDayInfoLength = 48;
+static const long BootAndSystemstampLength = 16;
+static const long BootstampLength = 8;
+static const unsigned long MaxPath = 260;
+
+
} //namespace winapi {
} //namespace interprocess {
} //namespace boost {
@@ -151,6 +177,20 @@
unsigned long dwHighDateTime;
};
+struct win32_find_data_t
+{
+ unsigned long dwFileAttributes;
+ interprocess_filetime ftCreationTime;
+ interprocess_filetime ftLastAccessTime;
+ interprocess_filetime ftLastWriteTime;
+ unsigned long nFileSizeHigh;
+ unsigned long nFileSizeLow;
+ unsigned long dwReserved0;
+ unsigned long dwReserved1;
+ char cFileName[MaxPath];
+ char cAlternateFileName[14];
+};
+
struct interprocess_security_attributes
{
unsigned long nLength;
@@ -208,6 +248,126 @@
interprocess_acl *Dacl;
} interprocess_security_descriptor;
+enum file_information_class_t {
+ file_directory_information = 1,
+ file_full_directory_information,
+ file_both_directory_information,
+ file_basic_information,
+ file_standard_information,
+ file_internal_information,
+ file_ea_information,
+ file_access_information,
+ file_name_information,
+ file_rename_information,
+ file_link_information,
+ file_names_information,
+ file_disposition_information,
+ file_position_information,
+ file_full_ea_information,
+ file_mode_information,
+ file_alignment_information,
+ file_all_information,
+ file_allocation_information,
+ file_end_of_file_information,
+ file_alternate_name_information,
+ file_stream_information,
+ file_pipe_information,
+ file_pipe_local_information,
+ file_pipe_remote_information,
+ file_mailslot_query_information,
+ file_mailslot_set_information,
+ file_compression_information,
+ file_copy_on_write_information,
+ file_completion_information,
+ file_move_cluster_information,
+ file_quota_information,
+ file_reparse_point_information,
+ file_network_open_information,
+ file_object_id_information,
+ file_tracking_information,
+ file_ole_directory_information,
+ file_content_index_information,
+ file_inherit_content_index_information,
+ file_ole_information,
+ file_maximum_information
+};
+
+struct file_name_information_t {
+ unsigned long FileNameLength;
+ wchar_t FileName[1];
+};
+
+struct file_rename_information_t {
+ int Replace;
+ void *RootDir;
+ unsigned long FileNameLength;
+ wchar_t FileName[1];
+};
+
+struct unicode_string_t {
+ unsigned short Length;
+ unsigned short MaximumLength;
+ wchar_t *Buffer;
+};
+
+struct object_attributes_t {
+ unsigned long Length;
+ void * RootDirectory;
+ unicode_string_t *ObjectName;
+ unsigned long Attributes;
+ void *SecurityDescriptor;
+ void *SecurityQualityOfService;
+};
+
+struct io_status_block_t {
+ union {
+ long Status;
+ void *Pointer;
+ };
+
+ unsigned long *Information;
+};
+
+union system_timeofday_information
+{
+ struct data_t
+ {
+ __int64 liKeBootTime;
+ __int64 liKeSystemTime;
+ __int64 liExpTimeZoneBias;
+ unsigned long uCurrentTimeZoneId;
+ unsigned long dwReserved;
+ } data;
+ unsigned char Reserved1[SystemTimeOfDayInfoLength];
+};
+
+enum system_information_class {
+ system_basic_information = 0,
+ system_performance_information = 2,
+ system_time_of_day_information = 3,
+ system_process_information = 5,
+ system_processor_performance_information = 8,
+ system_interrupt_information = 23,
+ system_exception_information = 33,
+ system_registry_quota_information = 37,
+ system_lookaside_information = 45
+};
+
+enum object_information_class
+{
+ object_basic_information,
+ object_name_information,
+ object_type_information,
+ object_all_information,
+ object_data_information
+};
+
+struct object_name_information_t
+{
+ unicode_string_t Name;
+ wchar_t NameBuffer[1];
+};
+
//Some windows API declarations
extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
@@ -220,6 +380,9 @@
, void *hTargetProcessHandle, void **lpTargetHandle
, unsigned long dwDesiredAccess, int bInheritHandle
, unsigned long dwOptions);
+extern "C" __declspec(dllimport) void *__stdcall FindFirstFileA(const char *lpFileName, win32_find_data_t *lpFindFileData);
+extern "C" __declspec(dllimport) int __stdcall FindNextFileA(void *hFindFile, win32_find_data_t *lpFindFileData);
+extern "C" __declspec(dllimport) int __stdcall FindClose(void *hFindFile);
extern "C" __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(interprocess_filetime*);
extern "C" __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const interprocess_filetime *in, const interprocess_filetime *out);
extern "C" __declspec(dllimport) void * __stdcall CreateMutexA(interprocess_security_attributes*, int, const char *);
@@ -245,6 +408,7 @@
std::va_list *Arguments);
extern "C" __declspec(dllimport) void *__stdcall LocalFree (void *);
extern "C" __declspec(dllimport) int __stdcall CreateDirectoryA(const char *, interprocess_security_attributes*);
+extern "C" __declspec(dllimport) int __stdcall RemoveDirectoryA(const char *lpPathName);
extern "C" __declspec(dllimport) int __stdcall GetTempPathA(unsigned long length, char *buffer);
extern "C" __declspec(dllimport) int __stdcall CreateDirectory(const char *, interprocess_security_attributes*);
extern "C" __declspec(dllimport) int __stdcall SetFileValidData(void *, __int64 size);
@@ -257,6 +421,25 @@
extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision);
extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted);
+extern "C" __declspec(dllimport) void *__stdcall LoadLibraryA(const char *);
+extern "C" __declspec(dllimport) int __stdcall FreeLibrary(void *);
+extern "C" __declspec(dllimport) void *__stdcall GetProcAddress(void *, const char*);
+extern "C" __declspec(dllimport) void *__stdcall GetModuleHandleA(const char*);
+
+//API function typedefs
+//Pointer to functions
+typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
+typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
+typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
+typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
+typedef long (__stdcall *NtClose_t) (void*);
+typedef long (__stdcall *RtlCreateUnicodeStringFromAsciiz_t)(unicode_string_t *, const char *);
+typedef void (__stdcall *RtlFreeUnicodeString_t)(unicode_string_t *);
+typedef void (__stdcall *RtlInitUnicodeString_t)( unicode_string_t *, const wchar_t * );
+typedef long (__stdcall *RtlAppendUnicodeToString_t)(unicode_string_t *Destination, const wchar_t *Source);
+typedef long (__stdcall * NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
+typedef long (__stdcall * NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
+typedef unsigned long (__stdcall * GetMappedFileName_t)(void *, void *, wchar_t *, unsigned long);
} //namespace winapi {
} //namespace interprocess {
@@ -298,6 +481,15 @@
static inline unsigned int close_handle(void* handle)
{ return CloseHandle(handle); }
+static inline void * find_first_file(const char *lpFileName, win32_find_data_t *lpFindFileData)
+{ return FindFirstFileA(lpFileName, lpFindFileData); }
+
+static inline bool find_next_file(void *hFindFile, win32_find_data_t *lpFindFileData)
+{ return FindNextFileA(hFindFile, lpFindFileData) != 0; }
+
+static inline bool find_close(void *handle)
+{ return FindClose(handle) != 0; }
+
static inline bool duplicate_current_process_handle
(void *hSourceHandle, void **lpTargetHandle)
{
@@ -384,6 +576,9 @@
static inline bool create_directory(const char *name, interprocess_security_attributes* security)
{ return 0 != CreateDirectoryA(name, security); }
+static inline bool remove_directory(const char *lpPathName)
+{ return 0 != RemoveDirectoryA(lpPathName); }
+
static inline unsigned long get_temp_path(unsigned long length, char *buffer)
{ return GetTempPathA(length, buffer); }
@@ -417,6 +612,274 @@
static inline long interlocked_exchange(long volatile* addend, long value)
{ return BOOST_INTERLOCKED_EXCHANGE(const_cast<long*>(addend), value); }
+//Forward functions
+static inline void *load_library(const char *name)
+{ return LoadLibraryA(name); }
+
+static inline bool free_library(void *module)
+{ return 0 != FreeLibrary(module); }
+
+static inline void *get_proc_address(void *module, const char *name)
+{ return GetProcAddress(module, name); }
+
+static inline void *get_current_process()
+{ return GetCurrentProcess(); }
+
+static inline void *get_module_handle(const char *name)
+{ return GetModuleHandleA(name); }
+
+static inline void initialize_object_attributes
+( object_attributes_t *pobject_attr, unicode_string_t *name
+ , unsigned long attr, void *rootdir, void *security_descr)
+
+{
+ pobject_attr->Length = sizeof(object_attributes_t);
+ pobject_attr->RootDirectory = rootdir;
+ pobject_attr->Attributes = attr;
+ pobject_attr->ObjectName = name;
+ pobject_attr->SecurityDescriptor = security_descr;
+ pobject_attr->SecurityQualityOfService = 0;
+}
+
+static inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf, unsigned short bufSize)
+{
+ ucStr->Buffer = buf;
+ ucStr->Length = 0;
+ ucStr->MaximumLength = bufSize;
+}
+
+//Complex winapi based functions...
+
+//pszFilename must have room for at least MaxPath+1 characters
+static inline bool get_file_name_from_handle_function
+ (void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length)
+{
+ if(length <= MaxPath){
+ return false;
+ }
+
+ void *hiPSAPI = load_library("PSAPI.DLL");
+ if (0 == hiPSAPI)
+ return 0;
+
+ class library_unloader
+ {
+ void *lib_;
+
+ public:
+ library_unloader(void *module) : lib_(module){}
+ ~library_unloader(){ free_library(lib_); }
+ } unloader(hiPSAPI);
+
+ // Pointer to function getMappedFileName() in PSAPI.DLL
+ GetMappedFileName_t pfGMFN =
+ (GetMappedFileName_t)get_proc_address(hiPSAPI, "GetMappedFileNameW");
+ if (! pfGMFN){
+ return 0; // Failed: unexpected error
+ }
+
+ bool bSuccess = false;
+
+ // Create a file mapping object.
+ void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0);
+ if(hFileMap)
+ {
+ // Create a file mapping to get the file name.
+ void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 0, 1, 0);
+
+ if (pMem){
+ out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
+ if(out_length){
+ bSuccess = true;
+ }
+ unmap_view_of_file(pMem);
+ }
+ close_handle(hFileMap);
+ }
+
+ return(bSuccess);
+}
+
+static inline bool get_system_time_of_day_information(system_timeofday_information &info)
+{
+ NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t)
+ get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation");
+ unsigned long res;
+ long status = pNtQuerySystemInformation(system_time_of_day_information, &info, sizeof(info), &res);
+ if(status){
+ return false;
+ }
+ return true;
+}
+
+static inline bool get_boot_time(unsigned char (&bootstamp) [BootstampLength])
+{
+ system_timeofday_information info;
+ bool ret = get_system_time_of_day_information(info);
+ if(!ret){
+ return false;
+ }
+ std::memcpy(&bootstamp[0], &info.Reserved1, sizeof(bootstamp));
+ return true;
+}
+
+static inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSystemstampLength])
+{
+ system_timeofday_information info;
+ bool ret = get_system_time_of_day_information(info);
+ if(!ret){
+ return false;
+ }
+ std::memcpy(&bootsystemstamp[0], &info.Reserved1, sizeof(bootsystemstamp));
+ return true;
+}
+
+static inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s) //will write BootstampLength chars
+{
+ if(s < (BootstampLength*2))
+ return false;
+ system_timeofday_information info;
+ bool ret = get_system_time_of_day_information(info);
+ if(!ret){
+ return false;
+ }
+ const char Characters [] =
+ { '0', '1', '2', '3', '4', '5', '6', '7'
+ , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ std::size_t char_counter = 0;
+ for(std::size_t i = 0; i != static_cast<std::size_t>(BootstampLength); ++i){
+ bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0xF0)>>4];
+ bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0x0F)];
+ }
+ s = BootstampLength*2;
+ return true;
+}
+
+static inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s) //will write BootAndSystemstampLength chars
+{
+ if(s < (BootAndSystemstampLength*2))
+ return false;
+ system_timeofday_information info;
+ bool ret = get_system_time_of_day_information(info);
+ if(!ret){
+ return false;
+ }
+ const wchar_t Characters [] =
+ { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7'
+ , L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
+ std::size_t char_counter = 0;
+ for(std::size_t i = 0; i != static_cast<std::size_t>(BootAndSystemstampLength); ++i){
+ bootsystemstamp[char_counter++] = Characters[(info.Reserved1[i]&0xF0)>>4];
+ bootsystemstamp[char_counter++] = Characters[(info.Reserved1[i]&0x0F)];
+ }
+ s = BootAndSystemstampLength*2;
+ return true;
+}
+
+static inline bool unlink_file(const char *filename)
+{
+ try{
+ NtSetInformationFile_t pNtSetInformationFile =
+ (NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
+ if(!pNtSetInformationFile){
+ return false;
+ }
+
+ NtQueryObject_t pNtQueryObject =
+ (NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
+
+ //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
+ void *fh = create_file(filename, generic_read | delete_access, open_existing,
+ file_flag_backup_semantics | file_flag_delete_on_close);
+ if(fh == invalid_handle_value){
+ return false;
+ }
+
+ class handle_closer
+ {
+ void *handle_;
+ public:
+ handle_closer(void *handle) : handle_(handle){}
+ ~handle_closer(){ close_handle(handle_); }
+ } handle_closer(fh);
+
+ const std::size_t CharArraySize = 32767; //Max name length
+
+ union mem_t
+ {
+ object_name_information_t name;
+ struct ren_t
+ {
+ file_rename_information_t info;
+ wchar_t buf[CharArraySize];
+ } ren;
+ };
+
+ class auto_ptr
+ {
+ public:
+ explicit auto_ptr(mem_t *ptr) : ptr_(ptr){}
+ ~auto_ptr(){ delete ptr_; }
+ mem_t *get() const{ return (ptr_); }
+ mem_t *operator->() const{ return this->get(); }
+ private:
+ mem_t *ptr_;
+ } pmem(new mem_t);
+
+ file_rename_information_t *pfri = (file_rename_information_t*)&pmem->ren.info;
+ const std::size_t RenMaxNumChars =
+ ((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
+
+ //Obtain file name
+ unsigned long size;
+ if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(mem_t), &size)){
+ return false;
+ }
+
+ //Copy filename to the rename member
+ std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
+ std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
+
+ //Second step: obtain the complete native-nt filename
+ //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){
+ //return 0;
+ //}
+
+ //Add trailing mark
+ if((RenMaxNumChars-filename_string_length) < (SystemTimeOfDayInfoLength*2)){
+ return false;
+ }
+
+ //Search '\\' character to replace it
+ for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
+ if(pmem->ren.info.FileName[--i] == L'\\')
+ break;
+ }
+
+ //Add random number
+ std::size_t s = RenMaxNumChars - filename_string_length;
+ if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
+ return false;
+ }
+ filename_string_length += s;
+
+ //Fill rename information (FileNameLength is in bytes)
+ pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
+ pfri->Replace = 1;
+ pfri->RootDir = 0;
+
+ //Final step: change the name of the in-use file:
+ io_status_block_t io;
+ if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(mem_t::ren_t), file_rename_information)){
+ return false;
+ }
+ return true;
+ }
+ catch(...){
+ return false;
+ }
+}
+
} //namespace winapi
} //namespace interprocess
} //namespace boost
Modified: trunk/boost/interprocess/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/detail/workaround.hpp (original)
+++ trunk/boost/interprocess/detail/workaround.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -13,7 +13,19 @@
#include <boost/interprocess/detail/config_begin.hpp>
-#if !(defined BOOST_WINDOWS) || (defined BOOST_DISABLE_WIN32)
+#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
+
+#define BOOST_INTERPROCESS_WINDOWS
+
+/*
+#if !defined(_MSC_EXTENSIONS)
+#error "Turn on Microsoft language extensions (_MSC_EXTENSIONS) to be able to call Windows API functions"
+#endif
+*/
+
+#endif
+
+#if !(defined BOOST_INTERPROCESS_WINDOWS)
#include <unistd.h>
@@ -30,10 +42,12 @@
# endif
#if ((_POSIX_SEMAPHORES - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
# if defined(__CYGWIN__)
#define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
# endif
+ #elif defined(__APPLE__)
+ # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
#endif
#if ((defined _V6_ILP32_OFFBIG) &&(_V6_ILP32_OFFBIG - 0 > 0)) ||\
@@ -51,10 +65,15 @@
#if ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
# define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
#else
+ //VMS and MACOS don't define it but the have shm_open/close interface
# if defined(__vms)
# if __CRTL_VER >= 70200000
# define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
# endif
+ # define BOOST_INTERPROCESS_SYSTEM_V_SHARED_MEMORY_OBJECTS
+ //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
+ //# elif defined (__APPLE__)
+ //# define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
# endif
#endif
@@ -76,7 +95,7 @@
#endif
#endif
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
#if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_RESOURCES)
#define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
#endif
@@ -88,34 +107,20 @@
#endif
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
-// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
-// passed on the command line, which in turn defines
-// __GXX_EXPERIMENTAL_CXX0X__. Note: __GXX_EXPERIMENTAL_CPP0X__ is
-// defined by some very early development versions of GCC 4.3; we will
-// remove this part of the check in the near future.
-# if defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__)
-# define BOOST_INTERPROCESS_RVALUE_REFERENCE
-# define BOOST_INTERPROCESS_VARIADIC_TEMPLATES
-# if defined(__GLIBCPP__) || defined(__GLIBCXX__)
-# define BOOST_INTERPROCESS_RVALUE_PAIR
-# endif
-# endif
-#endif
-
-#if defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && defined(BOOST_INTERPROCESS_VARIADIC_TEMPLATES)
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)\
+ && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
#define BOOST_INTERPROCESS_PERFECT_FORWARDING
#endif
//Now declare some Boost.Interprocess features depending on the implementation
-#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
+#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
#endif
-#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
+#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
Modified: trunk/boost/interprocess/errors.hpp
==============================================================================
--- trunk/boost/interprocess/errors.hpp (original)
+++ trunk/boost/interprocess/errors.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -33,7 +33,7 @@
#include <stdarg.h>
#include <string>
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
@@ -42,7 +42,7 @@
# else //ifdef BOOST_HAS_UNISTD_H
# error Unknown platform
# endif //ifdef BOOST_HAS_UNISTD_H
-#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
//!\file
//!Describes the error numbering of interprocess classes
@@ -52,7 +52,7 @@
/// @cond
static inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
{
- #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ #if (defined BOOST_INTERPROCESS_WINDOWS)
return winapi::get_last_error();
#else
return errno; // GCC 3.1 won't accept ::errno
@@ -60,7 +60,7 @@
}
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
inline void fill_system_message(int sys_err_code, std::string &str)
{
void *lpMsgBuf;
@@ -110,7 +110,9 @@
sem_error,
mode_error,
size_error,
- corrupted_error
+ corrupted_error,
+ not_such_file_or_directory,
+ invalid_argument
};
typedef int native_error_t;
@@ -124,7 +126,7 @@
static const ec_xlate ec_table[] =
{
- #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ #if (defined BOOST_INTERPROCESS_WINDOWS)
{ /*ERROR_ACCESS_DENIED*/5L, security_error },
{ /*ERROR_INVALID_ACCESS*/12L, security_error },
{ /*ERROR_SHARING_VIOLATION*/32L, security_error },
@@ -156,7 +158,7 @@
{ /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error },
{ /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error },
{ /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error }
- #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ #else //#if (defined BOOST_INTERPROCESS_WINDOWS)
{ EACCES, security_error },
{ EROFS, read_only_error },
{ EIO, io_error },
@@ -171,8 +173,10 @@
{ EISDIR, is_directory_error },
{ ENOSPC, out_of_space_error },
{ ENOMEM, out_of_memory_error },
- { EMFILE, out_of_resource_error }
- #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ { EMFILE, out_of_resource_error },
+ { ENOENT, not_such_file_or_directory },
+ { EINVAL, invalid_argument }
+ #endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
};
static inline error_code_t lookup_error(native_error_t err)
Modified: trunk/boost/interprocess/file_mapping.hpp
==============================================================================
--- trunk/boost/interprocess/file_mapping.hpp (original)
+++ trunk/boost/interprocess/file_mapping.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,8 +21,6 @@
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <string> //std::string
-#include <cstdio> //std::remove
-#include <string>
//!\file
//!Describes file_mapping and mapped region classes
@@ -30,31 +28,19 @@
namespace boost {
namespace interprocess {
-///@cond
-
-class file_mapping;
-
-//!Trait class to detect if a type is
-//!movable
-template<>
-struct is_movable<file_mapping>
-{
- enum { value = true };
-};
-
-///@endcond
-
//!A class that wraps a file-mapping that can be used to
//!create mapped regions from the mapped files
class file_mapping
{
/// @cond
//Non-copyable and non-assignable
- file_mapping(const file_mapping &);
- file_mapping &operator=(const file_mapping &);
+ file_mapping(file_mapping &);
+ file_mapping &operator=(file_mapping &);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(file_mapping)
+
//!Constructs an empty file mapping.
//!Does not throw
file_mapping();
@@ -68,41 +54,23 @@
//!Moves the ownership of "moved"'s file mapping object to *this.
//!After the call, "moved" does not represent any file mapping object.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- file_mapping(detail::moved_object<file_mapping> moved)
- : m_handle(file_handle_t(detail::invalid_file()))
- { this->swap(moved.get()); }
- #else
- file_mapping(file_mapping &&moved)
+ file_mapping(BOOST_INTERPROCESS_RV_REF(file_mapping) moved)
: m_handle(file_handle_t(detail::invalid_file()))
{ this->swap(moved); }
- #endif
//!Moves the ownership of "moved"'s file mapping to *this.
//!After the call, "moved" does not represent any file mapping.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- file_mapping &operator=(detail::moved_object<file_mapping> m_other)
- {
- file_mapping &moved = m_other.get();
- #else
- file_mapping &operator=(file_mapping &&moved)
- {
- #endif
- file_mapping tmp(detail::move_impl(moved));
+ file_mapping &operator=(BOOST_INTERPROCESS_RV_REF(file_mapping) moved)
+ {
+ file_mapping tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
//!Swaps to file_mappings.
//!Does not throw.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<file_mapping> mother)
- { this->swap(mother.get()); }
void swap(file_mapping &other);
- #else
- void swap(file_mapping &&other);
- #endif
//!Returns access mode
//!used in the constructor
@@ -120,6 +88,12 @@
//!used in the constructor.
const char *get_name() const;
+ //!Removes the file named "filename" even if it's been memory mapped.
+ //!Returns true on success.
+ //!The function might fail in some operating systems if the file is
+ //!being used other processes and no deletion permission was shared.
+ static bool remove(const char *filename);
+
/// @cond
private:
//!Closes a previously opened file mapping. Never throws.
@@ -140,11 +114,7 @@
inline const char *file_mapping::get_name() const
{ return m_filename.c_str(); }
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline void file_mapping::swap(file_mapping &other)
-#else
-inline void file_mapping::swap(file_mapping &&other)
-#endif
{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
@@ -179,6 +149,9 @@
m_mode = mode;
}
+inline bool file_mapping::remove(const char *filename)
+{ return detail::delete_file(filename); }
+
///@cond
inline void file_mapping::priv_close()
@@ -192,7 +165,7 @@
///@endcond
//!A class that stores the name of a file
-//!and call std::remove(name) in its destructor
+//!and tries to remove it in its destructor
//!Useful to remove temporary files in the presence
//!of exceptions
class remove_file_on_destroy
@@ -204,7 +177,7 @@
{}
~remove_file_on_destroy()
- { std::remove(m_name); }
+ { detail::delete_file(m_name); }
};
} //namespace interprocess {
Modified: trunk/boost/interprocess/indexes/iunordered_set_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/iunordered_set_index.hpp (original)
+++ trunk/boost/interprocess/indexes/iunordered_set_index.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -176,7 +176,7 @@
return old_size;
std::size_t received_size;
if(!alloc.allocation_command
- (try_shrink_in_place | nothrow_allocation, old_size, new_size, received_size, buckets).first){
+ (boost::interprocess::try_shrink_in_place | boost::interprocess::nothrow_allocation, old_size, new_size, received_size, buckets).first){
return old_size;
}
@@ -188,7 +188,7 @@
}
bucket_ptr shunk_p = alloc.allocation_command
- (shrink_in_place | nothrow_allocation, received_size, received_size, received_size, buckets).first;
+ (boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_size, received_size, received_size, buckets).first;
BOOST_ASSERT(buckets == shunk_p);
bucket_ptr buckets_init = buckets + received_size;
@@ -205,7 +205,7 @@
std::size_t received_size;
std::pair<bucket_ptr, bool> ret =
alloc.allocation_command
- (expand_fwd | allocate_new, new_num, new_num, received_size, old_buckets);
+ (boost::interprocess::expand_fwd | boost::interprocess::allocate_new, new_num, new_num, received_size, old_buckets);
if(ret.first == old_buckets){
bucket_ptr buckets_init = old_buckets + old_num;
for(std::size_t i = 0; i < (new_num - old_num); ++i){
Modified: trunk/boost/interprocess/interprocess_fwd.hpp
==============================================================================
--- trunk/boost/interprocess/interprocess_fwd.hpp (original)
+++ trunk/boost/interprocess/interprocess_fwd.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -11,12 +11,12 @@
#ifndef BOOST_INTERPROCESS_FWD_HPP
#define BOOST_INTERPROCESS_FWD_HPP
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#if defined (_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
-//#include <boost/interprocess/detail/config_begin.hpp>
-//#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
#include <cstddef>
@@ -61,9 +61,9 @@
class shared_memory_object;
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if defined (BOOST_INTERPROCESS_WINDOWS)
class windows_shared_memory;
-#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
//////////////////////////////////////////////////////////////////////////////
// mapped file/mapped region/mapped_file
@@ -113,6 +113,9 @@
template <class SharableMutex>
class sharable_lock;
+template <class UpgradableMutex>
+class upgradable_lock;
+
//////////////////////////////////////////////////////////////////////////////
// STL compatible allocators
//////////////////////////////////////////////////////////////////////////////
@@ -230,7 +233,7 @@
// Windows shared memory managed memory classes
//////////////////////////////////////////////////////////////////////////////
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if defined (BOOST_INTERPROCESS_WINDOWS)
template <class CharType
,class MemoryAlgorithm
@@ -249,7 +252,26 @@
,iset_index>
wmanaged_windows_shared_memory;
-#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#else
+
+template <class CharType
+ ,class MemoryAlgorithm
+ ,template<class IndexConfig> class IndexType>
+class basic_managed_xsi_shared_memory;
+
+typedef basic_managed_xsi_shared_memory
+ <char
+ ,rbtree_best_fit<mutex_family>
+ ,iset_index>
+managed_xsi_shared_memory;
+
+typedef basic_managed_xsi_shared_memory
+ <wchar_t
+ ,rbtree_best_fit<mutex_family>
+ ,iset_index>
+wmanaged_xsi_shared_memory;
+
+#endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
//////////////////////////////////////////////////////////////////////////////
// Fixed address shared memory
@@ -382,98 +404,12 @@
class message_queue;
+}} //namespace boost { namespace interprocess {
+
//////////////////////////////////////////////////////////////////////////////
-// Containers
+// CONTAINERS
//////////////////////////////////////////////////////////////////////////////
-//vector class
-template <class T
- ,class A = std::allocator<T> >
-class vector;
-
-//vector class
-template <class T
-,class A = std::allocator<T> >
-class deque;
-
-//list class
-template <class T
- ,class A = std::allocator<T> >
-class list;
-
-//slist class
-template <class T
- ,class Alloc = std::allocator<T> >
-class slist;
-
-//set class
-template <class T
- ,class Pred = std::less<T>
- ,class Alloc = std::allocator<T> >
-class set;
-
-//multiset class
-template <class T
- ,class Pred = std::less<T>
- ,class Alloc = std::allocator<T> >
-class multiset;
-
-//map class
-template <class Key
- ,class T
- ,class Pred = std::less<Key>
- ,class Alloc = std::allocator<std::pair<const Key, T> > >
-class map;
-
-//multimap class
-template <class Key
- ,class T
- ,class Pred = std::less<Key>
- ,class Alloc = std::allocator<std::pair<const Key, T> > >
-class multimap;
-
-//flat_set class
-template <class T
- ,class Pred = std::less<T>
- ,class Alloc = std::allocator<T> >
-class flat_set;
-
-//flat_multiset class
-template <class T
- ,class Pred = std::less<T>
- ,class Alloc = std::allocator<T> >
-class flat_multiset;
-
-//flat_map class
-template <class Key
- ,class T
- ,class Pred = std::less<Key>
- ,class Alloc = std::allocator<std::pair<Key, T> > >
-class flat_map;
-
-//flat_multimap class
-template <class Key
- ,class T
- ,class Pred = std::less<Key>
- ,class Alloc = std::allocator<std::pair<Key, T> > >
-class flat_multimap;
-
-//basic_string class
-template <class CharT
- ,class Traits = std::char_traits<CharT>
- ,class Alloc = std::allocator<CharT> >
-class basic_string;
-
-//string class
-typedef basic_string
- <char
- ,std::char_traits<char>
- ,std::allocator<char> >
-string;
-
-}} //namespace boost { namespace interprocess {
-
-//#include <boost/interprocess/detail/config_end.hpp>
+#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_FWD_HPP
-
Modified: trunk/boost/interprocess/managed_external_buffer.hpp
==============================================================================
--- trunk/boost/interprocess/managed_external_buffer.hpp (original)
+++ trunk/boost/interprocess/managed_external_buffer.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -43,9 +43,12 @@
/// @cond
typedef detail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType> base_t;
+ basic_managed_external_buffer(basic_managed_external_buffer&);
+ basic_managed_external_buffer & operator=(basic_managed_external_buffer&);
/// @endcond
-
+
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_external_buffer)
//!Default constructor. Does nothing.
//!Useful in combination with move semantics
@@ -75,25 +78,15 @@
}
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_external_buffer(detail::moved_object<basic_managed_external_buffer> mother)
- {
- basic_managed_external_buffer &moved = mother.get();
- #else
- basic_managed_external_buffer(basic_managed_external_buffer &&moved)
+ basic_managed_external_buffer(BOOST_INTERPROCESS_RV_REF(basic_managed_external_buffer) moved)
{
- #endif
this->swap(moved);
}
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_external_buffer &operator=(detail::moved_object<basic_managed_external_buffer> moved)
- #else
- basic_managed_external_buffer &operator=(basic_managed_external_buffer &&moved)
- #endif
+ basic_managed_external_buffer &operator=(BOOST_INTERPROCESS_RV_REF(basic_managed_external_buffer) moved)
{
- basic_managed_external_buffer tmp(detail::move_impl(moved));
+ basic_managed_external_buffer tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -103,36 +96,10 @@
//!Swaps the ownership of the managed heap memories managed by *this and other.
//!Never throws.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_managed_external_buffer> mother)
- { this->swap(mother.get()); }
void swap(basic_managed_external_buffer &other)
- #else
- void swap(basic_managed_external_buffer &&other)
- #endif
{ base_t::swap(other); }
};
-///@cond
-
-//!Trait class to detect if a type is
-//!movable
-template
- <
- class CharType,
- class AllocationAlgorithm,
- template<class IndexConfig> class IndexType
- >
-struct is_movable<basic_managed_external_buffer
- <CharType, AllocationAlgorithm, IndexType>
->
-{
- static const bool value = true;
-};
-
-///@endcond
-
-
} //namespace interprocess {
} //namespace boost {
Modified: trunk/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_heap_memory.hpp (original)
+++ trunk/boost/interprocess/managed_heap_memory.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -46,9 +46,12 @@
typedef detail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType> base_t;
+ basic_managed_heap_memory(basic_managed_heap_memory&);
+ basic_managed_heap_memory & operator=(basic_managed_heap_memory&);
/// @endcond
public: //functions
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_heap_memory)
//!Default constructor. Does nothing.
//!Useful in combination with move semantics
@@ -71,26 +74,13 @@
}
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_heap_memory
- (detail::moved_object<basic_managed_heap_memory> mother)
- {
- basic_managed_heap_memory &moved = mother.get();
- #else
- basic_managed_heap_memory(basic_managed_heap_memory &&moved)
- {
- #endif
- this->swap(moved);
- }
+ basic_managed_heap_memory(BOOST_INTERPROCESS_RV_REF(basic_managed_heap_memory) moved)
+ { this->swap(moved); }
//!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_heap_memory &operator=(detail::moved_object<basic_managed_heap_memory> moved)
- #else
- basic_managed_heap_memory &operator=(basic_managed_heap_memory &&moved)
- #endif
+ basic_managed_heap_memory &operator=(BOOST_INTERPROCESS_RV_REF(basic_managed_heap_memory) moved)
{
- basic_managed_heap_memory tmp(detail::move_impl(moved));
+ basic_managed_heap_memory tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -125,13 +115,7 @@
//!Swaps the ownership of the managed heap memories managed by *this and other.
//!Never throws.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_managed_heap_memory> mother)
- { this->swap(mother.get()); }
void swap(basic_managed_heap_memory &other)
- #else
- void swap(basic_managed_heap_memory &&other)
- #endif
{
base_t::swap(other);
m_heapmem.swap(other.m_heapmem);
@@ -150,27 +134,8 @@
/// @endcond
};
-///@cond
-
-//!Trait class to detect if a type is
-//!movable
-template
- <
- class CharType,
- class AllocationAlgorithm,
- template<class IndexConfig> class IndexType
- >
-struct is_movable<basic_managed_heap_memory
- <CharType, AllocationAlgorithm, IndexType>
->
-{
- static const bool value = true;
-};
-
-///@endcond
} //namespace interprocess {
-
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- trunk/boost/interprocess/managed_mapped_file.hpp (original)
+++ trunk/boost/interprocess/managed_mapped_file.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -47,6 +47,8 @@
<CharType, AllocationAlgorithm, IndexType,
detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset> base_t;
typedef detail::file_wrapper device_type;
+ basic_managed_mapped_file(basic_managed_mapped_file&);
+ basic_managed_mapped_file & operator=(basic_managed_mapped_file&);
private:
@@ -61,6 +63,7 @@
/// @endcond
public: //functions
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_mapped_file)
//!Creates mapped file and creates and places the segment manager.
//!This can throw.
@@ -118,27 +121,16 @@
//!Moves the ownership of "moved"'s managed memory to *this.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_mapped_file
- (detail::moved_object<basic_managed_mapped_file> mother)
- {
- basic_managed_mapped_file &moved = mother.get();
- #else
- basic_managed_mapped_file(basic_managed_mapped_file &&moved)
+ basic_managed_mapped_file(BOOST_INTERPROCESS_RV_REF(basic_managed_mapped_file) moved)
{
- #endif
this->swap(moved);
}
//!Moves the ownership of "moved"'s managed memory to *this.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_mapped_file &operator=(detail::moved_object<basic_managed_mapped_file> moved)
- #else
- basic_managed_mapped_file &operator=(basic_managed_mapped_file &&moved)
- #endif
+ basic_managed_mapped_file &operator=(BOOST_INTERPROCESS_RV_REF(basic_managed_mapped_file) moved)
{
- basic_managed_mapped_file tmp(detail::move_impl(moved));
+ basic_managed_mapped_file tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -154,14 +146,7 @@
//!Swaps the ownership of the managed mapped memories managed by *this and other.
//!Never throws.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_managed_mapped_file> mother)
- { this->swap(mother.get()); }
-
void swap(basic_managed_mapped_file &other)
- #else
- void swap(basic_managed_mapped_file &&other)
- #endif
{
base_t::swap(other);
m_mfile.swap(other.m_mfile);
@@ -214,27 +199,7 @@
/// @endcond
};
-///@cond
-
-//!Trait class to detect if a type is
-//!movable
-template
- <
- class CharType,
- class AllocationAlgorithm,
- template<class IndexConfig> class IndexType
- >
-struct is_movable<basic_managed_mapped_file
- <CharType, AllocationAlgorithm, IndexType>
->
-{
- static const bool value = true;
-};
-
-///@endcond
-
} //namespace interprocess {
-
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_shared_memory.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -60,9 +60,12 @@
private:
typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
+ basic_managed_shared_memory(basic_managed_shared_memory&);
+ basic_managed_shared_memory & operator=(basic_managed_shared_memory&);
/// @endcond
public: //functions
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_shared_memory)
//!Destroys *this and indicates that the calling process is finished using
//!the resource. The destructor function will deallocate
@@ -134,14 +137,8 @@
//!Moves the ownership of "moved"'s managed memory to *this.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_shared_memory(detail::moved_object<basic_managed_shared_memory> mother)
+ basic_managed_shared_memory(BOOST_INTERPROCESS_RV_REF(basic_managed_shared_memory) moved)
{
- basic_managed_shared_memory &moved = mother.get();
- #else
- basic_managed_shared_memory(basic_managed_shared_memory &&moved)
- {
- #endif
basic_managed_shared_memory tmp;
this->swap(moved);
tmp.swap(moved);
@@ -149,26 +146,16 @@
//!Moves the ownership of "moved"'s managed memory to *this.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_shared_memory &operator=(detail::moved_object<basic_managed_shared_memory> moved)
- #else
- basic_managed_shared_memory &operator=(basic_managed_shared_memory &&moved)
- #endif
+ basic_managed_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(basic_managed_shared_memory) moved)
{
- basic_managed_shared_memory tmp(detail::move_impl(moved));
+ basic_managed_shared_memory tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
//!Swaps the ownership of the managed shared memories managed by *this and other.
//!Never throws.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_managed_shared_memory> mother)
- { this->swap(mother.get()); }
void swap(basic_managed_shared_memory &other)
- #else
- void swap(basic_managed_shared_memory &&other)
- #endif
{
base_t::swap(other);
base2_t::swap(other);
@@ -179,20 +166,20 @@
//!
//!This function is not synchronized so no other thread or process should
//!be reading or writing the file
- static bool grow(const char *filename, std::size_t extra_bytes)
+ static bool grow(const char *shmname, std::size_t extra_bytes)
{
return base_t::template grow
- <basic_managed_shared_memory>(filename, extra_bytes);
+ <basic_managed_shared_memory>(shmname, extra_bytes);
}
//!Tries to resize the managed shared memory to minimized the size of the file.
//!
//!This function is not synchronized so no other thread or process should
//!be reading or writing the file
- static bool shrink_to_fit(const char *filename)
+ static bool shrink_to_fit(const char *shmname)
{
return base_t::template shrink_to_fit
- <basic_managed_shared_memory>(filename);
+ <basic_managed_shared_memory>(shmname);
}
/// @cond
@@ -214,25 +201,6 @@
/// @endcond
};
-///@cond
-
-//!Trait class to detect if a type is
-//!movable
-template
- <
- class CharType,
- class AllocationAlgorithm,
- template<class IndexConfig> class IndexType
- >
-struct is_movable<basic_managed_shared_memory
- <CharType, AllocationAlgorithm, IndexType>
->
-{
- static const bool value = true;
-};
-
-///@endcond
-
} //namespace interprocess {
} //namespace boost {
Modified: trunk/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_windows_shared_memory.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -60,9 +60,13 @@
private:
typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
+ basic_managed_windows_shared_memory(basic_managed_windows_shared_memory&);
+ basic_managed_windows_shared_memory & operator=(basic_managed_windows_shared_memory&);
+
/// @endcond
public: //functions
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_windows_shared_memory)
//!Default constructor. Does nothing.
//!Useful in combination with move semantics
@@ -121,24 +125,15 @@
//!Moves the ownership of "moved"'s managed memory to *this.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
basic_managed_windows_shared_memory
- (detail::moved_object<basic_managed_windows_shared_memory> moved)
- { this->swap(moved.get()); }
- #else
- basic_managed_windows_shared_memory(basic_managed_windows_shared_memory &&moved)
+ (BOOST_INTERPROCESS_RV_REF(basic_managed_windows_shared_memory) moved)
{ this->swap(moved); }
- #endif
//!Moves the ownership of "moved"'s managed memory to *this.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- basic_managed_windows_shared_memory &operator=(detail::moved_object<basic_managed_windows_shared_memory> moved)
- #else
- basic_managed_windows_shared_memory &operator=(basic_managed_windows_shared_memory &&moved)
- #endif
+ basic_managed_windows_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(basic_managed_windows_shared_memory) moved)
{
- basic_managed_windows_shared_memory tmp(detail::move_impl(moved));
+ basic_managed_windows_shared_memory tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -153,19 +148,14 @@
//!Swaps the ownership of the managed mapped memories managed by *this and other.
//!Never throws.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<basic_managed_windows_shared_memory> mother)
- { this->swap(mother.get()); }
void swap(basic_managed_windows_shared_memory &other)
- #else
- void swap(basic_managed_windows_shared_memory &&other)
- #endif
{
base_t::swap(other);
m_wshm.swap(other.m_wshm);
}
/// @cond
+
//!Tries to find a previous named allocation address. Returns a memory
//!buffer and the object count. If not found returned pointer is 0.
//!Never throws.
@@ -185,25 +175,6 @@
/// @endcond
};
-///@cond
-
-//!Trait class to detect if a type is
-//!movable
-template
- <
- class CharType,
- class AllocationAlgorithm,
- template<class IndexConfig> class IndexType
- >
-struct is_movable<basic_managed_windows_shared_memory
- <CharType, AllocationAlgorithm, IndexType>
->
-{
- static const bool value = true;
-};
-
-///@endcond
-
} //namespace interprocess {
} //namespace boost {
Modified: trunk/boost/interprocess/mapped_region.hpp
==============================================================================
--- trunk/boost/interprocess/mapped_region.hpp (original)
+++ trunk/boost/interprocess/mapped_region.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,7 +22,7 @@
#include <string>
#include <limits>
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
@@ -31,11 +31,13 @@
# include <unistd.h>
# include <sys/stat.h>
# include <sys/types.h>
+# include <sys/shm.h>
+# include <cassert>
# else
# error Unknown platform
# endif
-#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
//!\file
//!Describes memory_mappable and mapped region classes
@@ -55,11 +57,12 @@
{
/// @cond
//Non-copyable
- mapped_region(const mapped_region &);
- mapped_region &operator=(const mapped_region &);
+ mapped_region(mapped_region &);
+ mapped_region &operator=(mapped_region &);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(mapped_region)
//!Creates a mapping region of the mapped memory "mapping", starting in
//!offset "offset", and the mapping's size will be "size". The mapping
@@ -78,11 +81,7 @@
//!Move constructor. *this will be constructed taking ownership of "other"'s
//!region and "other" will be left in default constructor state.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- mapped_region(detail::moved_object<mapped_region> other);
- #else
- mapped_region(mapped_region &&other);
- #endif
+ mapped_region(BOOST_INTERPROCESS_RV_REF(mapped_region) other);
//!Destroys the mapped region.
//!Does not throw
@@ -90,11 +89,7 @@
//!Move assignment. If *this owns a memory mapped region, it will be
//!destroyed and it will take ownership of "other"'s memory mapped region.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- mapped_region &operator=(detail::moved_object<mapped_region> other);
- #else
- mapped_region &operator=(mapped_region &&other);
- #endif
+ mapped_region &operator=(BOOST_INTERPROCESS_RV_REF(mapped_region) other);
//!Returns the size of the mapping. Note for windows users: If
//!windows_shared_memory is mapped using 0 as the size, it returns 0
@@ -119,13 +114,7 @@
//!Swaps the mapped_region with another
//!mapped region
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<mapped_region> mother)
- { this->swap(mother.get()); }
void swap(mapped_region &other);
- #else
- void swap(mapped_region &&other);
- #endif
//!Returns the size of the page. This size is the minimum memory that
//!will be used by the system when mapping a memory mappable source.
@@ -148,8 +137,10 @@
offset_t m_offset;
offset_t m_extra_offset;
mode_t m_mode;
- #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
- file_handle_t m_file_mapping_hnd;
+ #if (defined BOOST_INTERPROCESS_WINDOWS)
+ file_handle_t m_file_mapping_hnd;
+ #else
+ bool m_is_xsi;
#endif
friend class detail::interprocess_tester;
@@ -163,14 +154,9 @@
inline void swap(mapped_region &x, mapped_region &y)
{ x.swap(y); }
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-inline mapped_region &mapped_region::operator=(detail::moved_object<mapped_region> moved)
-{
-#else
-inline mapped_region &mapped_region::operator=(mapped_region &&moved)
+inline mapped_region &mapped_region::operator=(BOOST_INTERPROCESS_RV_REF(mapped_region) moved)
{
-#endif
- mapped_region tmp(detail::move_impl(moved));
+ mapped_region tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -190,28 +176,19 @@
inline void* mapped_region::get_address() const
{ return m_base; }
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if (defined BOOST_INTERPROCESS_WINDOWS)
inline mapped_region::mapped_region()
: m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only)
, m_file_mapping_hnd(detail::invalid_file())
{}
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-inline mapped_region::mapped_region(detail::moved_object<mapped_region> other)
- : m_base(0), m_size(0), m_offset(0)
- , m_extra_offset(0)
- , m_mode(read_only)
- , m_file_mapping_hnd(detail::invalid_file())
-{ this->swap(other.get()); }
-#else
-inline mapped_region::mapped_region(mapped_region &&other)
+inline mapped_region::mapped_region(BOOST_INTERPROCESS_RV_REF(mapped_region) other)
: m_base(0), m_size(0), m_offset(0)
, m_extra_offset(0)
, m_mode(read_only)
, m_file_mapping_hnd(detail::invalid_file())
{ this->swap(other); }
-#endif
template<int dummy>
inline std::size_t mapped_region::page_size_holder<dummy>::get_page_size()
@@ -264,7 +241,9 @@
//Update mapping size if the user does not specify it
if(size == 0){
__int64 total_size;
- if(!winapi::get_file_size(detail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), total_size)){
+ if(!winapi::get_file_size
+ (detail::file_handle_from_mapping_handle
+ (mapping.get_mapping_handle()), total_size)){
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
@@ -382,11 +361,10 @@
inline void mapped_region::priv_close()
{
if(m_base){
- this->flush();
winapi::unmap_view_of_file(static_cast<char*>(m_base) - m_extra_offset);
m_base = 0;
}
- #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ #if (defined BOOST_INTERPROCESS_WINDOWS)
if(m_file_mapping_hnd != detail::invalid_file()){
winapi::close_handle(m_file_mapping_hnd);
m_file_mapping_hnd = detail::invalid_file();
@@ -397,22 +375,15 @@
inline void mapped_region::dont_close_on_destruction()
{}
-#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#else //#if (defined BOOST_INTERPROCESS_WINDOWS)
inline mapped_region::mapped_region()
- : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only)
+ : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only), m_is_xsi(false)
{}
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-inline mapped_region::mapped_region(detail::moved_object<mapped_region> other)
- : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only)
-{ this->swap(other.get()); }
-#else
-inline mapped_region::mapped_region(mapped_region &&other)
- : m_base(MAP_FAILED), m_size(0), m_offset(0), m_mode(read_only)
- , m_extra_offset(0)
+inline mapped_region::mapped_region(BOOST_INTERPROCESS_RV_REF(mapped_region) other)
+ : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only), m_is_xsi(false)
{ this->swap(other); }
-#endif
template<int dummy>
inline std::size_t mapped_region::page_size_holder<dummy>::get_page_size()
@@ -425,13 +396,55 @@
offset_t offset,
std::size_t size,
const void *address)
- : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(mode)
+ : m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(mode), m_is_xsi(false)
{
+ mapping_handle_t map_hnd = mapping.get_mapping_handle();
+
+ if(map_hnd.is_xsi){
+ //Get the size
+ ::shmid_ds xsi_ds;
+ int ret = ::shmctl(map_hnd.handle, IPC_STAT, &xsi_ds);
+ if(ret == -1){
+ error_info err(system_error_code());
+ throw interprocess_exception(err);
+ }
+ //Compare sizess
+ if(size == 0){
+ size = (std::size_t)xsi_ds.shm_segsz;
+ }
+ else if(size != (std::size_t)xsi_ds.shm_segsz){
+ error_info err(size_error);
+ throw interprocess_exception(err);
+ }
+ //Calculate flag
+ int flag = 0;
+ if(m_mode == read_only){
+ flag |= SHM_RDONLY;
+ }
+ else if(m_mode != read_write){
+ error_info err(mode_error);
+ throw interprocess_exception(err);
+ }
+ //Attach memory
+ void *base = ::shmat(map_hnd.handle, (void*)address, flag);
+ if(base == (void*)-1){
+ error_info err(system_error_code());
+ throw interprocess_exception(err);
+ }
+ //Update members
+ m_base = base;
+ m_offset = offset;
+ m_size = size;
+ m_mode = mode;
+ m_extra_offset = 0;
+ m_is_xsi = true;
+
+ return;
+ }
+
if(size == 0){
-// offset_t filesize = lseek64
offset_t filesize = lseek
- (mapping.get_mapping_handle(), offset, SEEK_END);
-
+ (map_hnd.handle, offset, SEEK_END);
if(filesize == -1 ){
error_info err(system_error_code());
throw interprocess_exception(err);
@@ -440,12 +453,13 @@
error_info err(size_error);
throw interprocess_exception(err);
}
+
filesize -= offset;
-
size = (size_t)filesize;
+
if((offset_t)size != filesize){
error_info err(size_error);
- throw interprocess_exception(err);
+ throw interprocess_exception(err);
}
}
@@ -459,7 +473,7 @@
prot |= PROT_READ;
flags |= MAP_SHARED;
break;
-
+
case read_write:
prot |= (PROT_WRITE | PROT_READ);
flags |= MAP_SHARED;
@@ -469,7 +483,7 @@
prot |= (PROT_WRITE | PROT_READ);
flags |= MAP_PRIVATE;
break;
-
+
default:
{
error_info err(mode_error);
@@ -496,7 +510,7 @@
, static_cast<std::size_t>(m_extra_offset + m_size)
, prot
, flags
- , mapping.get_mapping_handle()
+ , mapping.get_mapping_handle().handle
, offset - m_extra_offset);
//Check if mapping was successful
@@ -537,7 +551,12 @@
inline void mapped_region::priv_close()
{
if(m_base != MAP_FAILED){
- this->flush();
+ if(m_is_xsi){
+ int ret = ::shmdt(m_base);
+ assert(ret == 0);
+ (void)ret;
+ return;
+ }
munmap(static_cast<char*>(m_base) - m_extra_offset, m_size + m_extra_offset);
m_base = MAP_FAILED;
}
@@ -546,7 +565,7 @@
inline void mapped_region::dont_close_on_destruction()
{ m_base = MAP_FAILED; }
-#endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#endif //##if (defined BOOST_INTERPROCESS_WINDOWS)
template<int dummy>
const std::size_t mapped_region::page_size_holder<dummy>::PageSize
@@ -560,19 +579,17 @@
return page_size_holder<0>::PageSize;
}
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline void mapped_region::swap(mapped_region &other)
-#else
-inline void mapped_region::swap(mapped_region &&other)
-#endif
{
detail::do_swap(this->m_base, other.m_base);
detail::do_swap(this->m_size, other.m_size);
detail::do_swap(this->m_offset, other.m_offset);
detail::do_swap(this->m_extra_offset, other.m_extra_offset);
- detail::do_swap(this->m_mode, other.m_mode);
- #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ detail::do_swap(this->m_mode, other.m_mode);
+ #if (defined BOOST_INTERPROCESS_WINDOWS)
detail::do_swap(this->m_file_mapping_hnd, other.m_file_mapping_hnd);
+ #else
+ detail::do_swap(this->m_is_xsi, other.m_is_xsi);
#endif
}
@@ -583,13 +600,6 @@
{ return true; }
};
-//!Trait class to detect if a type is
-//!movable
-template<>
-struct is_movable<mapped_region>
-{
- enum { value = true };
-};
/// @endcond
} //namespace interprocess {
Modified: trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,14 +19,17 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
#include <boost/interprocess/detail/math_functions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/move.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
+#include <algorithm>
+#include <utility>
+#include <iterator>
//!\file
//!Implements common operations for memory algorithms.
@@ -36,207 +39,528 @@
namespace detail {
template<class VoidPointer>
-struct multi_allocation_next
+class basic_multiallocation_slist
{
- typedef typename detail::
- pointer_to_other<VoidPointer, multi_allocation_next>::type
- multi_allocation_next_ptr;
+ public:
+ typedef VoidPointer void_pointer;
- multi_allocation_next(multi_allocation_next_ptr n)
- : next_(n)
- {}
- multi_allocation_next_ptr next_;
-};
+ private:
+ static VoidPointer &priv_get_ref(const VoidPointer &p)
+ { return *static_cast<void_pointer*>(detail::get_pointer(p)); }
-//!This iterator is returned by "allocate_many" functions so that
-//!the user can access the multiple buffers allocated in a single call
-template<class VoidPointer>
-class basic_multiallocation_iterator
- : public std::iterator<std::input_iterator_tag, char>
-{
- void unspecified_bool_type_func() const {}
- typedef void (basic_multiallocation_iterator::*unspecified_bool_type)() const;
- typedef typename detail::
- pointer_to_other
- <VoidPointer, multi_allocation_next<VoidPointer> >::type
- multi_allocation_next_ptr;
+ basic_multiallocation_slist(basic_multiallocation_slist &);
+ basic_multiallocation_slist &operator=(basic_multiallocation_slist &);
public:
- typedef char value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_slist)
+
+ //!This iterator is returned by "allocate_many" functions so that
+ //!the user can access the multiple buffers allocated in a single call
+ class iterator
+ : public std::iterator<std::input_iterator_tag, char>
+ {
+ friend class basic_multiallocation_slist<void_pointer>;
+ void unspecified_bool_type_func() const {}
+ typedef void (iterator::*unspecified_bool_type)() const;
+
+ iterator(void_pointer node_range)
+ : next_node_(node_range)
+ {}
+
+ public:
+ typedef char value_type;
+ typedef value_type & reference;
+ typedef value_type * pointer;
+
+ iterator()
+ : next_node_(0)
+ {}
+
+ iterator &operator=(const iterator &other)
+ { next_node_ = other.next_node_; return *this; }
+
+ public:
+ iterator& operator++()
+ {
+ next_node_ = *static_cast<void_pointer*>(detail::get_pointer(next_node_));
+ return *this;
+ }
+
+ iterator operator++(int)
+ {
+ iterator result(*this);
+ ++*this;
+ return result;
+ }
+
+ bool operator== (const iterator& other) const
+ { return next_node_ == other.next_node_; }
- basic_multiallocation_iterator()
- : next_alloc_(0)
+ bool operator!= (const iterator& other) const
+ { return !operator== (other); }
+
+ reference operator*() const
+ { return *static_cast<char*>(detail::get_pointer(next_node_)); }
+
+ operator unspecified_bool_type() const
+ { return next_node_? &iterator::unspecified_bool_type_func : 0; }
+
+ pointer operator->() const
+ { return &(*(*this)); }
+
+ private:
+ void_pointer next_node_;
+ };
+
+ private:
+ iterator it_;
+
+ public:
+ basic_multiallocation_slist()
+ : it_(iterator())
{}
- basic_multiallocation_iterator(multi_allocation_next_ptr next)
- : next_alloc_(next)
+ basic_multiallocation_slist(void_pointer p)
+ : it_(p ? iterator_to(p) : iterator())
{}
- basic_multiallocation_iterator &operator=(const basic_multiallocation_iterator &other)
- { next_alloc_ = other.next_alloc_; return *this; }
+ basic_multiallocation_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
+ : it_(iterator())
+ { this->swap(other); }
- public:
- basic_multiallocation_iterator& operator++()
- { next_alloc_.next_ = detail::get_pointer(next_alloc_.next_->next_); return *this; }
-
- basic_multiallocation_iterator operator++(int)
+ basic_multiallocation_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
{
- basic_multiallocation_iterator result(next_alloc_.next_);
- ++*this;
- return result;
+ basic_multiallocation_slist tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
}
- bool operator== (const basic_multiallocation_iterator& other) const
- { return next_alloc_.next_ == other.next_alloc_.next_; }
+ bool empty() const
+ { return !it_; }
- bool operator!= (const basic_multiallocation_iterator& other) const
- { return !operator== (other); }
+ iterator before_begin() const
+ { return iterator(void_pointer(const_cast<void*>(static_cast<const void*>(&it_.next_node_)))); }
- reference operator*() const
- { return *reinterpret_cast<char*>(detail::get_pointer(next_alloc_.next_)); }
+ iterator begin() const
+ { return it_; }
- operator unspecified_bool_type() const
- { return next_alloc_.next_? &basic_multiallocation_iterator::unspecified_bool_type_func : 0; }
+ iterator end() const
+ { return iterator(); }
- pointer operator->() const
- { return &(*(*this)); }
+ void clear()
+ { this->it_.next_node_ = void_pointer(0); }
- static basic_multiallocation_iterator create_simple_range(void *mem)
+ iterator insert_after(iterator it, void_pointer m)
{
- basic_multiallocation_iterator it;
- typedef multi_allocation_next<VoidPointer> next_impl_t;
- next_impl_t * tmp_mem = static_cast<next_impl_t*>(mem);
- it = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
- tmp_mem->next_ = 0;
- return it;
+ priv_get_ref(m) = priv_get_ref(it.next_node_);
+ priv_get_ref(it.next_node_) = m;
+ return iterator(m);
}
- multi_allocation_next<VoidPointer> &get_multi_allocation_next()
- { return *next_alloc_.next_; }
+ void push_front(void_pointer m)
+ {
+ priv_get_ref(m) = this->it_.next_node_;
+ this->it_.next_node_ = m;
+ }
- private:
- multi_allocation_next<VoidPointer> next_alloc_;
+ void pop_front()
+ { ++it_; }
+
+ void *front() const
+ { return detail::get_pointer(it_.next_node_); }
+
+ void splice_after(iterator after_this, iterator before_begin, iterator before_end)
+ {
+ if (after_this != before_begin && after_this != before_end && before_begin != before_end) {
+ void_pointer next_b = priv_get_ref(before_begin.next_node_);
+ void_pointer next_e = priv_get_ref(before_end.next_node_);
+ void_pointer next_p = priv_get_ref(after_this.next_node_);
+ priv_get_ref(before_begin.next_node_) = next_e;
+ priv_get_ref(before_end.next_node_) = next_p;
+ priv_get_ref(after_this.next_node_) = next_b;
+ }
+ }
+
+ void swap(basic_multiallocation_slist &other_chain)
+ {
+ std::swap(this->it_, other_chain.it_);
+ }
+
+ static iterator iterator_to(void_pointer p)
+ { return iterator(p); }
+
+ void_pointer extract_data()
+ {
+ void_pointer ret = empty() ? void_pointer(0) : void_pointer(&*it_);
+ it_ = iterator();
+ return ret;
+ }
};
template<class VoidPointer>
-class basic_multiallocation_chain
+class basic_multiallocation_cached_slist
{
private:
- basic_multiallocation_iterator<VoidPointer> it_;
- VoidPointer last_mem_;
- std::size_t num_mem_;
+ basic_multiallocation_slist<VoidPointer> slist_;
+ typename basic_multiallocation_slist<VoidPointer>::iterator last_;
- basic_multiallocation_chain(const basic_multiallocation_chain &);
- basic_multiallocation_chain &operator=(const basic_multiallocation_chain &);
+ basic_multiallocation_cached_slist(basic_multiallocation_cached_slist &);
+ basic_multiallocation_cached_slist &operator=(basic_multiallocation_cached_slist &);
public:
- typedef basic_multiallocation_iterator<VoidPointer> multiallocation_iterator;
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_slist)
+
+ typedef typename basic_multiallocation_slist<VoidPointer>::void_pointer void_pointer;
+ typedef typename basic_multiallocation_slist<VoidPointer>::iterator iterator;
- basic_multiallocation_chain()
- : it_(0), last_mem_(0), num_mem_(0)
+ basic_multiallocation_cached_slist()
+ : slist_(), last_(slist_.before_begin())
{}
+/*
+ basic_multiallocation_cached_slist(iterator first_node)
+ : slist_(first_node), last_(slist_.before_begin())
+ {
+ iterator end;
+ while(first_node != end){
+ ++last_;
+ }
+ }*/
+
+ basic_multiallocation_cached_slist(void_pointer p1, void_pointer p2)
+ : slist_(p1), last_(p2 ? iterator_to(p2) : slist_.before_begin())
+ {}
+
+ basic_multiallocation_cached_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
+ : slist_(), last_(slist_.before_begin())
+ { this->swap(other); }
- void reset()
+ basic_multiallocation_cached_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
{
- this->it_ = multiallocation_iterator();
- this->last_mem_ = 0;
- this->num_mem_ = 0;
+ basic_multiallocation_cached_slist tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
}
- void push_back(void *mem)
+ bool empty() const
+ { return slist_.empty(); }
+
+ iterator before_begin() const
+ { return slist_.before_begin(); }
+
+ iterator begin() const
+ { return slist_.begin(); }
+
+ iterator end() const
+ { return slist_.end(); }
+
+ iterator last() const
+ { return last_; }
+
+ void clear()
{
- typedef multi_allocation_next<VoidPointer> next_impl_t;
- next_impl_t * tmp_mem = static_cast<next_impl_t*>(mem);
-
- if(!this->last_mem_){
- this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
- }
- else{
- static_cast<next_impl_t*>(detail::get_pointer(this->last_mem_))->next_ = tmp_mem;
- }
- tmp_mem->next_ = 0;
- this->last_mem_ = tmp_mem;
- ++num_mem_;
+ slist_.clear();
+ last_ = slist_.before_begin();
}
- void push_front(void *mem)
+ iterator insert_after(iterator it, void_pointer m)
{
- typedef multi_allocation_next<VoidPointer> next_impl_t;
- next_impl_t * tmp_mem = static_cast<next_impl_t*>(mem);
- ++num_mem_;
-
- if(!this->last_mem_){
- this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
- tmp_mem->next_ = 0;
- this->last_mem_ = tmp_mem;
- }
- else{
- next_impl_t * old_first = &this->it_.get_multi_allocation_next();
- tmp_mem->next_ = old_first;
- this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
+ slist_.insert_after(it, m);
+ if(it == last_){
+ last_ = slist_.iterator_to(m);
}
+ return iterator_to(m);
}
- void swap(basic_multiallocation_chain &other_chain)
+ void push_front(void_pointer m)
+ { this->insert_after(this->before_begin(), m); }
+
+ void push_back(void_pointer m)
+ { this->insert_after(last_, m); }
+
+ void pop_front()
{
- std::swap(this->it_, other_chain.it_);
- std::swap(this->last_mem_, other_chain.last_mem_);
- std::swap(this->num_mem_, other_chain.num_mem_);
+ if(last_ == slist_.begin()){
+ last_ = slist_.before_begin();
+ }
+ slist_.pop_front();
}
- void splice_back(basic_multiallocation_chain &other_chain)
+ void *front() const
+ { return slist_.front(); }
+
+ void splice_after(iterator after_this, iterator before_begin, iterator before_end)
{
- typedef multi_allocation_next<VoidPointer> next_impl_t;
- multiallocation_iterator end_it;
- multiallocation_iterator other_it = other_chain.get_it();
- multiallocation_iterator this_it = this->get_it();
- if(end_it == other_it){
+ if(before_begin == before_end)
return;
+ if(after_this == last_){
+ last_ = before_end;
}
- else if(end_it == this_it){
- this->swap(other_chain);
+ slist_.splice_after(after_this, before_begin, before_end);
+ }
+
+ void swap(basic_multiallocation_cached_slist &x)
+ {
+ slist_.swap(x.slist_);
+ using std::swap;
+ swap(last_, x.last_);
+ if(last_ == x.before_begin()){
+ last_ = this->before_begin();
}
- else{
- static_cast<next_impl_t*>(detail::get_pointer(this->last_mem_))->next_
- = &other_chain.it_.get_multi_allocation_next();
- this->last_mem_ = other_chain.last_mem_;
- this->num_mem_ += other_chain.num_mem_;
+ if(x.last_ == this->before_begin()){
+ x.last_ = x.before_begin();
}
}
- void *pop_front()
+ static iterator iterator_to(void_pointer p)
+ { return basic_multiallocation_slist<VoidPointer>::iterator_to(p); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
{
- multiallocation_iterator itend;
- if(this->it_ == itend){
- this->last_mem_= 0;
- this->num_mem_ = 0;
- return 0;
+ if(this->empty()){
+ return std::pair<void_pointer, void_pointer>(void_pointer(0), void_pointer(0));
}
else{
- void *addr = &*it_;
- ++it_;
- --num_mem_;
- if(!num_mem_){
- this->last_mem_ = 0;
- this->it_ = multiallocation_iterator();
- }
- return addr;
+ void_pointer p1 = slist_.extract_data();
+ void_pointer p2 = void_pointer(&*last_);
+ last_ = iterator();
+ return std::pair<void_pointer, void_pointer>(p1, p2);
}
}
+};
- bool empty() const
- { return !num_mem_; }
+template<class MultiallocatorCachedSlist>
+class basic_multiallocation_cached_counted_slist
+{
+ private:
+ MultiallocatorCachedSlist cached_slist_;
+ std::size_t size_;
+
+ basic_multiallocation_cached_counted_slist(basic_multiallocation_cached_counted_slist &);
+ basic_multiallocation_cached_counted_slist &operator=(basic_multiallocation_cached_counted_slist &);
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_counted_slist)
+
+ typedef typename MultiallocatorCachedSlist::void_pointer void_pointer;
+ typedef typename MultiallocatorCachedSlist::iterator iterator;
- multiallocation_iterator get_it() const
- { return it_; }
+ basic_multiallocation_cached_counted_slist()
+ : cached_slist_(), size_(0)
+ {}
+
+ basic_multiallocation_cached_counted_slist(void_pointer p1, void_pointer p2, std::size_t n)
+ : cached_slist_(p1, p2), size_(n)
+ {}
+
+ basic_multiallocation_cached_counted_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
+ : cached_slist_(), size_(0)
+ { this->swap(other); }
+
+ basic_multiallocation_cached_counted_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
+ {
+ basic_multiallocation_cached_counted_slist tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ basic_multiallocation_cached_counted_slist (MultiallocatorCachedSlist mem, std::size_t n)
+ : cached_slist_(boost::interprocess::move(mem)), size_(n)
+ {}
+
+ bool empty() const
+ { return cached_slist_.empty(); }
std::size_t size() const
- { return num_mem_; }
+ { return size_; }
+
+ iterator before_begin() const
+ { return cached_slist_.before_begin(); }
+
+ iterator begin() const
+ { return cached_slist_.begin(); }
+
+ iterator end() const
+ { return cached_slist_.end(); }
+
+ iterator last() const
+ { return cached_slist_.last(); }
+
+ void clear()
+ {
+ cached_slist_.clear();
+ size_ = 0;
+ }
+
+ iterator insert_after(iterator it, void_pointer m)
+ {
+ iterator ret = cached_slist_.insert_after(it, m);
+ ++size_;
+ return ret;
+ }
+
+ void push_front(void_pointer m)
+ { this->insert_after(this->before_begin(), m); }
+
+ void push_back(void_pointer m)
+ { this->insert_after(this->before_begin(), m); }
+
+ void pop_front()
+ {
+ cached_slist_.pop_front();
+ --size_;
+ }
+
+ void *front() const
+ { return cached_slist_.front(); }
+
+ void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end)
+ {
+ std::size_t n = static_cast<std::size_t>(std::distance(before_begin, before_end));
+ this->splice_after(after_this, x, before_begin, before_end, n);
+ }
+
+ void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end, std::size_t n)
+ {
+ cached_slist_.splice_after(after_this, before_begin, before_end);
+ size_ += n;
+ x.size_ -= n;
+ }
+
+ void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x)
+ {
+ cached_slist_.splice_after(after_this, x.before_begin(), x.last());
+ size_ += x.size_;
+ x.size_ = 0;
+ }
+
+ void swap(basic_multiallocation_cached_counted_slist &x)
+ {
+ cached_slist_.swap(x.cached_slist_);
+ using std::swap;
+ swap(size_, x.size_);
+ }
+
+ static iterator iterator_to(void_pointer p)
+ { return MultiallocatorCachedSlist::iterator_to(p); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ {
+ size_ = 0;
+ return cached_slist_.extract_data();
+ }
+};
+
+template<class T>
+struct cast_functor
+{
+ typedef typename detail::add_reference<T>::type result_type;
+ result_type operator()(char &ptr) const
+ { return *static_cast<T*>(static_cast<void*>(&ptr)); }
};
+template<class MultiallocationChain, class T>
+class transform_multiallocation_chain
+{
+private:
+
+ MultiallocationChain holder_;
+ typedef typename MultiallocationChain::void_pointer void_pointer;
+ typedef typename boost::pointer_to_other
+ <void_pointer, T>::type pointer;
+
+ transform_multiallocation_chain(transform_multiallocation_chain &);
+ transform_multiallocation_chain &operator=(transform_multiallocation_chain &);
+
+ static pointer cast(void_pointer p)
+ {
+ return pointer(static_cast<T*>(detail::get_pointer(p)));
+ }
+
+public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(transform_multiallocation_chain)
+
+ typedef transform_iterator
+ < typename MultiallocationChain::iterator
+ , detail::cast_functor <T> > iterator;
+
+ transform_multiallocation_chain(void_pointer p1, void_pointer p2, std::size_t n)
+ : holder_(p1, p2, n)
+ {}
+
+ transform_multiallocation_chain()
+ : holder_()
+ {}
+
+ transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
+ : holder_()
+ { this->swap(other); }
+
+ transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(MultiallocationChain) other)
+ : holder_(boost::interprocess::move(other))
+ {}
+
+ transform_multiallocation_chain& operator=(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
+ {
+ transform_multiallocation_chain tmp(boost::interprocess::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ void push_front(pointer mem)
+ { holder_.push_front(mem); }
+
+ void swap(transform_multiallocation_chain &other_chain)
+ { holder_.swap(other_chain.holder_); }
+ /*
+ void splice_after(iterator after_this, iterator before_begin, iterator before_end)
+ { holder_.splice_after(after_this.base(), before_begin.base(), before_end.base()); }
+ */
+ void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
+ { holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
+
+ void pop_front()
+ { holder_.pop_front(); }
+
+ pointer front() const
+ { return cast(holder_.front()); }
+
+ bool empty() const
+ { return holder_.empty(); }
+
+ iterator before_begin() const
+ { return iterator(holder_.before_begin()); }
+
+ iterator begin() const
+ { return iterator(holder_.begin()); }
+
+ iterator end() const
+ { return iterator(holder_.end()); }
+
+ iterator last() const
+ { return iterator(holder_.last()); }
+
+ std::size_t size() const
+ { return holder_.size(); }
+
+ void clear()
+ { holder_.clear(); }
+
+ iterator insert_after(iterator it, pointer m)
+ { return iterator(holder_.insert_after(it.base(), m)); }
+
+ static iterator iterator_to(pointer p)
+ { return iterator(MultiallocationChain::iterator_to(p)); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ { return holder_.extract_data(); }
+
+ MultiallocationChain extract_multiallocation_chain()
+ {
+ return MultiallocationChain(boost::interprocess::move(holder_));
+ }
+};
+
//!This class implements several allocation functions shared by different algorithms
//!(aligned allocation, multiple allocation...).
template<class MemoryAlgorithm>
@@ -245,19 +569,16 @@
public:
typedef typename MemoryAlgorithm::void_pointer void_pointer;
typedef typename MemoryAlgorithm::block_ctrl block_ctrl;
- typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator;
- typedef multi_allocation_next<void_pointer> multi_allocation_next_t;
- typedef typename multi_allocation_next_t::
- multi_allocation_next_ptr multi_allocation_next_ptr;
+ typedef typename MemoryAlgorithm::multiallocation_chain multiallocation_chain;
typedef memory_algorithm_common<MemoryAlgorithm> this_type;
- static const std::size_t Alignment = MemoryAlgorithm::Alignment;
- static const std::size_t MinBlockUnits = MemoryAlgorithm::MinBlockUnits;
- static const std::size_t AllocatedCtrlBytes = MemoryAlgorithm::AllocatedCtrlBytes;
- static const std::size_t AllocatedCtrlUnits = MemoryAlgorithm::AllocatedCtrlUnits;
- static const std::size_t BlockCtrlBytes = MemoryAlgorithm::BlockCtrlBytes;
- static const std::size_t BlockCtrlUnits = MemoryAlgorithm::BlockCtrlUnits;
- static const std::size_t UsableByPreviousChunk = MemoryAlgorithm::UsableByPreviousChunk;
+ static const std::size_t Alignment = MemoryAlgorithm::Alignment;
+ static const std::size_t MinBlockUnits = MemoryAlgorithm::MinBlockUnits;
+ static const std::size_t AllocatedCtrlBytes = MemoryAlgorithm::AllocatedCtrlBytes;
+ static const std::size_t AllocatedCtrlUnits = MemoryAlgorithm::AllocatedCtrlUnits;
+ static const std::size_t BlockCtrlBytes = MemoryAlgorithm::BlockCtrlBytes;
+ static const std::size_t BlockCtrlUnits = MemoryAlgorithm::BlockCtrlUnits;
+ static const std::size_t UsableByPreviousChunk = MemoryAlgorithm::UsableByPreviousChunk;
static void assert_alignment(const void *ptr)
{ assert_alignment((std::size_t)ptr); }
@@ -280,12 +601,17 @@
static std::size_t multiple_of_units(std::size_t size)
{ return detail::get_rounded_size(size, Alignment); }
- static multiallocation_iterator allocate_many
+ static multiallocation_chain allocate_many
(MemoryAlgorithm *memory_algo, std::size_t elem_bytes, std::size_t n_elements)
{
return this_type::priv_allocate_many(memory_algo, &elem_bytes, n_elements, 0);
}
+ static void deallocate_many(MemoryAlgorithm *memory_algo, multiallocation_chain chain)
+ {
+ return this_type::priv_deallocate_many(memory_algo, boost::interprocess::move(chain));
+ }
+
static bool calculate_lcm_and_needs_backwards_lcmed
(std::size_t backwards_multiple, std::size_t received_size, std::size_t size_to_achieve,
std::size_t &lcm_out, std::size_t &needs_backwards_lcmed_out)
@@ -381,7 +707,7 @@
return true;
}
- static multiallocation_iterator allocate_many
+ static multiallocation_chain allocate_many
( MemoryAlgorithm *memory_algo
, const std::size_t *elem_sizes
, std::size_t n_elements
@@ -403,7 +729,8 @@
std::size_t real_size;
if(alignment <= Alignment){
- return memory_algo->priv_allocate(allocate_new, nbytes, nbytes, real_size).first;
+ return memory_algo->priv_allocate
+ (boost::interprocess::allocate_new, nbytes, nbytes, real_size).first;
}
if(nbytes > UsableByPreviousChunk)
@@ -428,7 +755,8 @@
);
//Now allocate the buffer
- void *buffer = memory_algo->priv_allocate(allocate_new, request, request, real_size).first;
+ void *buffer = memory_algo->priv_allocate
+ (boost::interprocess::allocate_new, request, request, real_size).first;
if(!buffer){
return 0;
}
@@ -608,7 +936,7 @@
}
private:
- static multiallocation_iterator priv_allocate_many
+ static multiallocation_chain priv_allocate_many
( MemoryAlgorithm *memory_algo
, const std::size_t *elem_sizes
, std::size_t n_elements
@@ -620,7 +948,7 @@
//Calculate the total size of all requests
std::size_t total_request_units = 0;
std::size_t elem_units = 0;
- const std::size_t ptr_size_units = memory_algo->priv_get_total_units(sizeof(multi_allocation_next_ptr));
+ const std::size_t ptr_size_units = memory_algo->priv_get_total_units(sizeof(void_pointer));
if(!sizeof_element){
elem_units = memory_algo->priv_get_total_units(*elem_sizes);
elem_units = ptr_size_units > elem_units ? ptr_size_units : elem_units;
@@ -634,7 +962,8 @@
}
}
- multi_allocation_next_ptr first = 0, previous = 0;
+ multiallocation_chain chain;
+
std::size_t low_idx = 0;
while(low_idx < n_elements){
std::size_t total_bytes = total_request_units*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk;
@@ -645,7 +974,7 @@
std::size_t received_size;
std::pair<void *, bool> ret = memory_algo->priv_allocate
- (allocate_new, min_allocation, total_bytes, received_size, 0);
+ (boost::interprocess::allocate_new, min_allocation, total_bytes, received_size, 0);
if(!ret.first){
break;
}
@@ -710,33 +1039,28 @@
block_address += new_block->m_size*Alignment;
total_used_units += new_block->m_size;
//Check we have enough room to overwrite the intrusive pointer
- assert((new_block->m_size*Alignment - AllocatedCtrlUnits) >= sizeof(multi_allocation_next_t));
- multi_allocation_next_ptr p = new(memory_algo->priv_get_user_buffer(new_block))multi_allocation_next_t(0);
-
- if(!first){
- first = p;
- }
- else{
- previous->next_ = p;
- }
- previous = p;
+ assert((new_block->m_size*Alignment - AllocatedCtrlUnits) >= sizeof(void_pointer));
+ void_pointer p = new(memory_algo->priv_get_user_buffer(new_block))void_pointer(0);
+ chain.push_back(p);
++low_idx;
//prev_block = new_block;
}
//Sanity check
BOOST_ASSERT(total_used_units == received_units);
}
-
+
if(low_idx != n_elements){
- while(first){
- multi_allocation_next_ptr prev = first;
- first = first->next_;
- memory_algo->priv_deallocate(detail::get_pointer(prev));
- }
- return multiallocation_iterator();
+ priv_deallocate_many(memory_algo, boost::interprocess::move(chain));
}
- else{
- return multiallocation_iterator(first);
+ return boost::interprocess::move(chain);
+ }
+
+ static void priv_deallocate_many(MemoryAlgorithm *memory_algo, multiallocation_chain chain)
+ {
+ while(!chain.empty()){
+ void *addr = detail::get_pointer(chain.front());
+ chain.pop_front();
+ memory_algo->priv_deallocate(addr);
}
}
};
Modified: trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,8 +18,10 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -67,7 +69,7 @@
private:
struct block_ctrl;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, block_ctrl>::type block_ctrl_ptr;
/*!Block control structure*/
@@ -149,7 +151,7 @@
void clear_free_memory();
std::pair<void *, bool>
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
void *reuse_ptr = 0, std::size_t backwards_multiple = 1);
@@ -169,7 +171,7 @@
private:
/*!Real allocation algorithm with min allocation option*/
- std::pair<void *, bool> priv_allocate(allocation_type command
+ std::pair<void *, bool> priv_allocate(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -188,7 +190,7 @@
,std::size_t &received_size);
/*!Real expand to both sides implementation*/
- void* priv_expand_both_sides(allocation_type command
+ void* priv_expand_both_sides(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -375,7 +377,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
std::size_t ignore;
- return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ return priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
}
template<class MutexFamily, class VoidPointer>
@@ -390,7 +392,7 @@
template<class MutexFamily, class VoidPointer>
inline std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
- allocation_command (allocation_type command, std::size_t min_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t min_size,
std::size_t preferred_size,std::size_t &received_size,
void *reuse_ptr, std::size_t backwards_multiple)
{
@@ -398,7 +400,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
(void)backwards_multiple;
- command &= ~expand_bwd;
+ command &= ~boost::interprocess::expand_bwd;
if(!command)
return std::pair<void *, bool>(0, false);
return priv_allocate(command, min_size, preferred_size, received_size, reuse_ptr);
@@ -426,7 +428,7 @@
//Multisegment pointer. Let's try first the normal allocation
//since it's faster.
std::size_t ignore;
- void *addr = this->priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ void *addr = this->priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
if(!addr){
//If this fails we will try the allocation through the segment
//creator.
@@ -447,7 +449,7 @@
p_services->create_new_segment(MinBlockSize > nbytes ? MinBlockSize : nbytes);
if(ret.first){
priv_add_segment(ret.first, ret.second);
- addr = this->priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ addr = this->priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
}
}
return addr;
@@ -455,7 +457,7 @@
template<class MutexFamily, class VoidPointer>
void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_expand_both_sides(allocation_type command
+ priv_expand_both_sides(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -471,14 +473,14 @@
return reuse_ptr;
}
- if(command & expand_fwd){
+ if(command & boost::interprocess::expand_fwd){
if(priv_expand(reuse_ptr, min_size, preferred_size, received_size))
return reuse_ptr;
}
else{
received_size = this->size(reuse_ptr);
}
- if(command & expand_bwd){
+ if(command & boost::interprocess::expand_bwd){
std::size_t extra_forward = !received_size ? 0 : received_size + BlockCtrlBytes;
prev_block_t prev_pair = priv_prev_block_if_free(reuse);
block_ctrl *prev = prev_pair.second;
@@ -534,13 +536,13 @@
template<class MutexFamily, class VoidPointer>
std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_allocate(allocation_type command
+ priv_allocate(boost::interprocess::allocation_type command
,std::size_t limit_size
,std::size_t preferred_size
,std::size_t &received_size
,void *reuse_ptr)
{
- if(command & shrink_in_place){
+ if(command & boost::interprocess::shrink_in_place){
bool success =
this->priv_shrink(reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
@@ -565,14 +567,14 @@
//Expand in place
//reuse_ptr, limit_size, preferred_size, received_size
//
- if(reuse_ptr && (command & (expand_fwd | expand_bwd))){
+ if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
void *ret = priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, true);
if(ret)
return return_type(ret, true);
}
- if(command & allocate_new){
+ if(command & boost::interprocess::allocate_new){
received_size = 0;
while(block != root){
//Update biggest block pointers
@@ -600,7 +602,7 @@
}
}
//Now try to expand both sides with min size
- if(reuse_ptr && (command & (expand_fwd | expand_bwd))){
+ if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
return return_type(priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, false), true);
}
@@ -809,12 +811,12 @@
std::size_t ignore;
if(alignment <= Alignment){
- return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ return priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
}
std::size_t request =
nbytes + alignment + MinBlockSize*Alignment - BlockCtrlBytes;
- void *buffer = priv_allocate(allocate_new, request, request, ignore).first;
+ void *buffer = priv_allocate(boost::interprocess::allocate_new, request, request, ignore).first;
if(!buffer)
return 0;
else if ((((std::size_t)(buffer)) % alignment) == 0)
Modified: trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,8 +18,10 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -61,15 +63,13 @@
typedef MutexFamily mutex_family;
//!Pointer type to be used with the rest of the Interprocess framework
typedef VoidPointer void_pointer;
-
- typedef detail::basic_multiallocation_iterator
- <void_pointer> multiallocation_iterator;
- typedef detail::basic_multiallocation_chain
- <void_pointer> multiallocation_chain;
+ typedef detail::basic_multiallocation_cached_slist<void_pointer> multialloc_cached;
+ typedef detail::basic_multiallocation_cached_counted_slist
+ <multialloc_cached> multiallocation_chain;
private:
class block_ctrl;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, block_ctrl>::type block_ctrl_ptr;
class block_ctrl;
@@ -109,7 +109,6 @@
std::size_t m_extra_hdr_bytes;
} m_header;
- friend class detail::basic_multiallocation_iterator<void_pointer>;
friend class detail::memory_algorithm_common<simple_seq_fit_impl>;
typedef detail::memory_algorithm_common<simple_seq_fit_impl> algo_impl_t;
@@ -134,13 +133,27 @@
/// @cond
//!Multiple element allocation, same size
- multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements);
+ multiallocation_chain
+ allocate_many(std::size_t elem_bytes, std::size_t num_elements)
+ {
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ return algo_impl_t::allocate_many(this, elem_bytes, num_elements);
+ }
//!Multiple element allocation, different size
- multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
+ multiallocation_chain
+ allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
+ {
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
+ }
//!Multiple element deallocation
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
/// @endcond
@@ -171,12 +184,12 @@
template<class T>
std::pair<T *, bool>
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr = 0);
std::pair<void *, bool>
- raw_allocation_command (allocation_type command, std::size_t limit_size,
+ raw_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
void *reuse_ptr = 0, std::size_t sizeof_object = 1);
@@ -196,13 +209,13 @@
static block_ctrl *priv_get_block(const void *ptr);
//!Real allocation algorithm with min allocation option
- std::pair<void *, bool> priv_allocate(allocation_type command
+ std::pair<void *, bool> priv_allocate(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
,void *reuse_ptr = 0);
- std::pair<void *, bool> priv_allocation_command(allocation_type command
+ std::pair<void *, bool> priv_allocation_command(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -233,7 +246,7 @@
,std::size_t &received_size);
//!Real expand to both sides implementation
- void* priv_expand_both_sides(allocation_type command
+ void* priv_expand_both_sides(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -386,7 +399,7 @@
if(!m_header.m_allocated){
assert(prev == root);
std::size_t ignore;
- unique_block = priv_allocate(allocate_new, 0, 0, ignore).first;
+ unique_block = priv_allocate(boost::interprocess::allocate_new, 0, 0, ignore).first;
if(!unique_block)
return;
last = detail::get_pointer(m_header.m_root.m_next);
@@ -547,7 +560,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
std::size_t ignore;
- return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ return priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
}
template<class MutexFamily, class VoidPointer>
@@ -564,7 +577,7 @@
template<class MutexFamily, class VoidPointer>
template<class T>
inline std::pair<T*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr)
{
@@ -577,13 +590,13 @@
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
- raw_allocation_command (allocation_type command, std::size_t limit_objects,
+ raw_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_objects,
std::size_t preferred_objects,std::size_t &received_objects,
void *reuse_ptr, std::size_t sizeof_object)
{
if(!sizeof_object)
return std::pair<void *, bool>(static_cast<void*>(0), 0);
- if(command & try_shrink_in_place){
+ if(command & boost::interprocess::try_shrink_in_place){
bool success = algo_impl_t::try_shrink
( this, reuse_ptr, limit_objects*sizeof_object
, preferred_objects*sizeof_object, received_objects);
@@ -596,11 +609,11 @@
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_allocation_command (allocation_type command, std::size_t limit_size,
+ priv_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size, std::size_t &received_size,
void *reuse_ptr, std::size_t sizeof_object)
{
- command &= ~expand_bwd;
+ command &= ~boost::interprocess::expand_bwd;
if(!command) return std::pair<void *, bool>(static_cast<void*>(0), false);
std::pair<void*, bool> ret;
@@ -634,7 +647,7 @@
template<class MutexFamily, class VoidPointer>
void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_expand_both_sides(allocation_type command
+ priv_expand_both_sides(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -650,14 +663,14 @@
return reuse_ptr;
}
- if(command & expand_fwd){
+ if(command & boost::interprocess::expand_fwd){
if(priv_expand(reuse_ptr, min_size, preferred_size, received_size))
return reuse_ptr;
}
else{
received_size = this->size(reuse_ptr);
}
- if(command & expand_bwd){
+ if(command & boost::interprocess::expand_bwd){
std::size_t extra_forward = !received_size ? 0 : received_size + BlockCtrlBytes;
prev_block_t prev_pair = priv_prev_block_if_free(reuse);
block_ctrl *prev = prev_pair.second;
@@ -712,43 +725,20 @@
}
template<class MutexFamily, class VoidPointer>
-inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator
- simple_seq_fit_impl<MutexFamily, VoidPointer>::
- allocate_many(std::size_t elem_bytes, std::size_t num_elements)
-{
- //-----------------------
- boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
- //-----------------------
- return algo_impl_t::
- allocate_many(this, elem_bytes, num_elements);
-}
-
-template<class MutexFamily, class VoidPointer>
inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::
- deallocate_many(typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator it)
+ deallocate_many(typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_chain chain)
{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- while(it){
- void *addr = &*it;
- ++it;
+ while(!chain.empty()){
+ void *addr = chain.front();
+ chain.pop_front();
this->priv_deallocate(addr);
}
}
template<class MutexFamily, class VoidPointer>
-inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator
- simple_seq_fit_impl<MutexFamily, VoidPointer>::
- allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
-{
- //-----------------------
- boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
- //-----------------------
- return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
-}
-
-template<class MutexFamily, class VoidPointer>
inline std::size_t simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_get_total_units(std::size_t userbytes)
{
@@ -759,13 +749,13 @@
template<class MutexFamily, class VoidPointer>
std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_allocate(allocation_type command
+ priv_allocate(boost::interprocess::allocation_type command
,std::size_t limit_size
,std::size_t preferred_size
,std::size_t &received_size
,void *reuse_ptr)
{
- if(command & shrink_in_place){
+ if(command & boost::interprocess::shrink_in_place){
bool success =
algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
@@ -790,7 +780,7 @@
//Expand in place
//reuse_ptr, limit_size, preferred_size, received_size
//
- if(reuse_ptr && (command & (expand_fwd | expand_bwd))){
+ if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
void *ret = priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, true);
if(ret){
@@ -799,7 +789,7 @@
}
}
- if(command & allocate_new){
+ if(command & boost::interprocess::allocate_new){
received_size = 0;
while(block != root){
//Update biggest block pointers
@@ -835,7 +825,7 @@
}
}
//Now try to expand both sides with min size
- if(reuse_ptr && (command & (expand_fwd | expand_bwd))){
+ if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
return_type ret (priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, false), true);
algo_impl_t::assert_alignment(ret.first);
Modified: trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,9 +18,11 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -40,15 +42,7 @@
#include <cassert>
#include <new>
-//#define BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
-
-#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
#include <boost/intrusive/set.hpp>
-#else
-//#include <boost/intrusive/splay_set.hpp>
-//#include <boost/intrusive/avl_set.hpp>
-#include <boost/intrusive/sg_set.hpp>
-#endif
//!\file
//!Describes a best-fit algorithm based in an intrusive red-black tree used to allocate
@@ -75,35 +69,26 @@
typedef MutexFamily mutex_family;
//!Pointer type to be used with the rest of the Interprocess framework
typedef VoidPointer void_pointer;
- typedef detail::basic_multiallocation_iterator
- <void_pointer> multiallocation_iterator;
- typedef detail::basic_multiallocation_chain
- <void_pointer> multiallocation_chain;
+ //typedef detail::basic_multiallocation_cached_counted_slist<void_pointer> multiallocation_chain;
+
+ typedef detail::basic_multiallocation_cached_slist<void_pointer> multialloc_cached;
+ typedef detail::basic_multiallocation_cached_counted_slist
+ <multialloc_cached> multiallocation_chain;
/// @cond
private:
struct block_ctrl;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, block_ctrl>::type block_ctrl_ptr;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<void_pointer, char>::type char_ptr;
-#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
typedef typename bi::make_set_base_hook
-#else
-// typedef typename bi::make_splay_set_base_hook
-// typedef typename bi::make_avl_set_base_hook
- typedef typename bi::make_sg_set_base_hook
-#endif
< bi::void_pointer<VoidPointer>
, bi::optimize_size<true>
, bi::link_mode<bi::normal_link> >::type TreeHook;
- typedef detail::multi_allocation_next<void_pointer> multi_allocation_next_t;
- typedef typename multi_allocation_next_t::
- multi_allocation_next_ptr multi_allocation_next_ptr;
-
struct SizeHolder
{
//!This block's memory size (including block_ctrl
@@ -138,13 +123,7 @@
//!Shared interprocess_mutex to protect memory allocate/deallocate
typedef typename MutexFamily::mutex_type interprocess_mutex;
-#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
typedef typename bi::make_multiset
-#else
- //typedef typename bi::make_splay_multiset
- //typedef typename bi::make_avl_multiset
- typedef typename bi::make_sg_multiset
-#endif
<block_ctrl, bi::base_hook<TreeHook> >::type Imultiset;
typedef typename Imultiset::iterator imultiset_iterator;
@@ -163,7 +142,6 @@
std::size_t m_size;
} m_header;
- friend class detail::basic_multiallocation_iterator<void_pointer>;
friend class detail::memory_algorithm_common<rbtree_best_fit>;
typedef detail::memory_algorithm_common<rbtree_best_fit> algo_impl_t;
@@ -192,13 +170,27 @@
//Experimental. Dont' use
//!Multiple element allocation, same size
- multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements);
+ multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements)
+ {
+
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ return algo_impl_t::allocate_many(this, elem_bytes, num_elements);
+ }
//!Multiple element allocation, different size
- multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
+ multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
+ {
+
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
+ }
//!Multiple element allocation, different size
- void deallocate_many(multiallocation_iterator it);
+ void deallocate_many(multiallocation_chain chain);
/// @endcond
@@ -231,12 +223,12 @@
template<class T>
std::pair<T *, bool>
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr = 0);
std::pair<void *, bool>
- raw_allocation_command (allocation_type command, std::size_t limit_object,
+ raw_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_object,
std::size_t preferred_object,std::size_t &received_object,
void *reuse_ptr = 0, std::size_t sizeof_object = 1);
@@ -252,13 +244,13 @@
static std::size_t priv_first_block_offset(const void *this_ptr, std::size_t extra_hdr_bytes);
std::pair<void*, bool>
- priv_allocation_command(allocation_type command, std::size_t limit_size,
+ priv_allocation_command(boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
void *reuse_ptr, std::size_t sizeof_object);
//!Real allocation algorithm with min allocation option
- std::pair<void *, bool> priv_allocate(allocation_type command
+ std::pair<void *, bool> priv_allocate(boost::interprocess::allocation_type command
,std::size_t limit_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -281,7 +273,7 @@
,std::size_t &received_size);
//!Real expand to both sides implementation
- void* priv_expand_both_sides(allocation_type command
+ void* priv_expand_both_sides(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -463,7 +455,7 @@
block_ctrl *last_block;
if(priv_next_block(first_block) == old_end_block){
std::size_t ignore;
- unique_buffer = priv_allocate(allocate_new, 0, 0, ignore).first;
+ unique_buffer = priv_allocate(boost::interprocess::allocate_new, 0, 0, ignore).first;
if(!unique_buffer)
return;
algo_impl_t::assert_alignment(unique_buffer);
@@ -631,7 +623,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
std::size_t ignore;
- void * ret = priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ void * ret = priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
return ret;
}
@@ -648,7 +640,7 @@
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
template<class T>
inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr)
{
@@ -661,13 +653,13 @@
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- raw_allocation_command (allocation_type command, std::size_t limit_objects,
+ raw_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_objects,
std::size_t preferred_objects,std::size_t &received_objects,
void *reuse_ptr, std::size_t sizeof_object)
{
if(!sizeof_object)
return std::pair<void *, bool>(static_cast<void*>(0), 0);
- if(command & try_shrink_in_place){
+ if(command & boost::interprocess::try_shrink_in_place){
bool success = algo_impl_t::try_shrink
( this, reuse_ptr, limit_objects*sizeof_object
, preferred_objects*sizeof_object, received_objects);
@@ -681,7 +673,7 @@
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- priv_allocation_command (allocation_type command, std::size_t limit_size,
+ priv_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
void *reuse_ptr, std::size_t sizeof_object)
{
@@ -732,7 +724,7 @@
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- priv_expand_both_sides(allocation_type command
+ priv_expand_both_sides(boost::interprocess::allocation_type command
,std::size_t min_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -741,7 +733,7 @@
,std::size_t backwards_multiple)
{
algo_impl_t::assert_alignment(reuse_ptr);
- if(command & expand_fwd){
+ if(command & boost::interprocess::expand_fwd){
if(priv_expand(reuse_ptr, min_size, preferred_size, received_size))
return reuse_ptr;
}
@@ -756,7 +748,7 @@
BOOST_ASSERT(0 == (preferred_size % backwards_multiple));
}
- if(command & expand_bwd){
+ if(command & boost::interprocess::expand_bwd){
//Obtain the real size of the block
block_ctrl *reuse = priv_get_block(reuse_ptr);
@@ -791,7 +783,7 @@
//Check if previous block has enough size
if(std::size_t(prev_block->m_size*Alignment) >= needs_backwards_aligned){
//Now take all next space. This will succeed
- if(command & expand_fwd){
+ if(command & boost::interprocess::expand_fwd){
std::size_t received_size2;
if(!priv_expand(reuse_ptr, received_size, received_size, received_size2)){
assert(0);
@@ -874,44 +866,18 @@
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
-inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_iterator
- rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- allocate_many(std::size_t elem_bytes, std::size_t num_elements)
-{
- //-----------------------
- boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
- //-----------------------
- return algo_impl_t::allocate_many(this, elem_bytes, num_elements);
-}
-
-template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- deallocate_many(typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_iterator it)
-{
- //-----------------------
- boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
- //-----------------------
- while(it){
- void *addr = &*it;
- ++it;
- this->priv_deallocate(addr);
- }
-}
-
-template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
-inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_iterator
- rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
+ deallocate_many(typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_chain chain)
{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
+ algo_impl_t::deallocate_many(this, boost::interprocess::move(chain));
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
- priv_allocate(allocation_type command
+ priv_allocate(boost::interprocess::allocation_type command
,std::size_t limit_size
,std::size_t preferred_size
,std::size_t &received_size
@@ -919,9 +885,9 @@
,std::size_t backwards_multiple)
{
//Remove me. Forbid backwards allocation
- //command &= (~expand_bwd);
+ //command &= (~boost::interprocess::expand_bwd);
- if(command & shrink_in_place){
+ if(command & boost::interprocess::shrink_in_place){
bool success =
algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
@@ -940,14 +906,14 @@
std::size_t limit_units = priv_get_total_units(limit_size);
//Expand in place
- if(reuse_ptr && (command & (expand_fwd | expand_bwd))){
+ if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
void *ret = priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, true, backwards_multiple);
if(ret)
return return_type(ret, true);
}
- if(command & allocate_new){
+ if(command & boost::interprocess::allocate_new){
size_block_ctrl_compare comp;
imultiset_iterator it(m_header.m_imultiset.lower_bound(preferred_units, comp));
@@ -965,7 +931,7 @@
//Now try to expand both sides with min size
- if(reuse_ptr && (command & (expand_fwd | expand_bwd))){
+ if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
return return_type(priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, false, backwards_multiple), true);
}
Modified: trunk/boost/interprocess/offset_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/offset_ptr.hpp (original)
+++ trunk/boost/interprocess/offset_ptr.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -162,7 +162,11 @@
//!Dereferencing operator, if it is a null offset_ptr behavior
//! is undefined. Never throws.
reference operator* () const
- { return *(this->get()); }
+ {
+ pointer p = this->get();
+ reference r = *p;
+ return r;
+ }
//!Indexing operator.
//!Never throws.
Modified: trunk/boost/interprocess/segment_manager.hpp
==============================================================================
--- trunk/boost/interprocess/segment_manager.hpp (original)
+++ trunk/boost/interprocess/segment_manager.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,7 +21,7 @@
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
+#include <boost/interprocess/detail/transform_iterator.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/segment_manager_helper.hpp>
@@ -72,8 +72,7 @@
/// @cond
//Experimental. Don't use
- typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator;
- typedef typename MemoryAlgorithm::multiallocation_chain multiallocation_chain;
+ typedef typename MemoryAlgorithm::multiallocation_chain multiallocation_chain;
/// @endcond
@@ -123,38 +122,40 @@
//Experimental. Dont' use.
//!Allocates n_elements of
//!elem_size bytes. Throws bad_alloc on failure.
- multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements)
+ multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements)
{
- multiallocation_iterator ret = MemoryAlgorithm::allocate_many(elem_bytes, num_elements);
- if(!ret) throw bad_alloc();
- return ret;
+ multiallocation_chain mem(MemoryAlgorithm::allocate_many(elem_bytes, num_elements));
+ if(mem.empty()) throw bad_alloc();
+ return boost::interprocess::move(mem);
}
//!Allocates n_elements, each one of
//!element_lenghts[i]*sizeof_element bytes. Throws bad_alloc on failure.
- multiallocation_iterator allocate_many
+ multiallocation_chain allocate_many
(const std::size_t *element_lenghts, std::size_t n_elements, std::size_t sizeof_element = 1)
{
- multiallocation_iterator ret = MemoryAlgorithm::allocate_many(element_lenghts, n_elements, sizeof_element);
- if(!ret) throw bad_alloc();
- return ret;
+ multiallocation_chain mem(MemoryAlgorithm::allocate_many(element_lenghts, n_elements, sizeof_element));
+ if(mem.empty()) throw bad_alloc();
+ return boost::interprocess::move(mem);
}
//!Allocates n_elements of
//!elem_size bytes. Returns a default constructed iterator on failure.
- multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t)
+ multiallocation_chain allocate_many
+ (std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t)
{ return MemoryAlgorithm::allocate_many(elem_bytes, num_elements); }
//!Allocates n_elements, each one of
//!element_lenghts[i]*sizeof_element bytes.
//!Returns a default constructed iterator on failure.
- multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element, std::nothrow_t)
+ multiallocation_chain allocate_many
+ (const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element, std::nothrow_t)
{ return MemoryAlgorithm::allocate_many(elem_sizes, n_elements, sizeof_element); }
//!Deallocates elements pointed by the
//!multiallocation iterator range.
- void deallocate_many(multiallocation_iterator it)
- { MemoryAlgorithm::deallocate_many(it); }
+ void deallocate_many(multiallocation_chain chain)
+ { MemoryAlgorithm::deallocate_many(boost::interprocess::move(chain)); }
/// @endcond
@@ -185,27 +186,27 @@
template<class T>
std::pair<T *, bool>
- allocation_command (allocation_type command, std::size_t limit_size,
+ allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr = 0)
{
std::pair<T *, bool> ret = MemoryAlgorithm::allocation_command
- ( command | nothrow_allocation, limit_size, preferred_size, received_size
+ ( command | boost::interprocess::nothrow_allocation, limit_size, preferred_size, received_size
, reuse_ptr);
- if(!(command & nothrow_allocation) && !ret.first)
+ if(!(command & boost::interprocess::nothrow_allocation) && !ret.first)
throw bad_alloc();
return ret;
}
std::pair<void *, bool>
- raw_allocation_command (allocation_type command, std::size_t limit_objects,
+ raw_allocation_command (boost::interprocess::allocation_type command, std::size_t limit_objects,
std::size_t preferred_objects,std::size_t &received_objects,
void *reuse_ptr = 0, std::size_t sizeof_object = 1)
{
std::pair<void *, bool> ret = MemoryAlgorithm::raw_allocation_command
- ( command | nothrow_allocation, limit_objects, preferred_objects, received_objects
+ ( command | boost::interprocess::nothrow_allocation, limit_objects, preferred_objects, received_objects
, reuse_ptr, sizeof_object);
- if(!(command & nothrow_allocation) && !ret.first)
+ if(!(command & boost::interprocess::nothrow_allocation) && !ret.first)
throw bad_alloc();
return ret;
}
@@ -297,7 +298,7 @@
//scoped_lock<rmutex> guard(m_header);
//-------------------------------
- if(ctrl_data->allocation_type() != anonymous_type){
+ if(ctrl_data->alloc_type() != anonymous_type){
//This is not an anonymous object, the pointer is wrong!
assert(0);
}
@@ -311,11 +312,6 @@
/// @endcond
};
-//These pointers are the ones the user will use to
-//indicate previous allocation types
-static const detail::anonymous_instance_t * anonymous_instance = 0;
-static const detail::unique_instance_t * unique_instance = 0;
-
//!This object is placed in the beginning of memory segment and
//!implements the allocation (named or anonymous) of portions
//!of the segment. This object contains two indexes that
@@ -351,7 +347,6 @@
typedef MemoryAlgorithm memory_algorithm;
typedef typename Base::void_pointer void_pointer;
typedef CharType char_type;
- typedef typename Base::multiallocation_iterator multiallocation_iterator;
typedef segment_manager_base<MemoryAlgorithm> segment_manager_base_type;
@@ -672,6 +667,7 @@
typename deleter<T>::type
get_deleter()
{ return typename deleter<T>::type(this); }
+
/// @cond
//!Generic named/anonymous new function. Offers all the possibilities,
@@ -753,7 +749,7 @@
void priv_destroy_ptr(const void *ptr, detail::in_place_interface &dtor)
{
block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr, dtor.size, dtor.alignment);
- switch(ctrl_data->allocation_type()){
+ switch(ctrl_data->alloc_type()){
case anonymous_type:
this->prot_anonymous_destroy(ptr, dtor);
break;
@@ -779,7 +775,7 @@
//!functions. Does not throw
static const CharType *priv_get_instance_name(block_header_t *ctrl_data)
{
- allocation_type type = ctrl_data->allocation_type();
+ boost::interprocess::allocation_type type = ctrl_data->alloc_type();
if(type != named_type){
assert((type == anonymous_type && ctrl_data->m_num_char == 0) ||
(type == unique_type && ctrl_data->m_num_char != 0) );
@@ -805,8 +801,8 @@
static instance_type priv_get_instance_type(block_header_t *ctrl_data)
{
//Get header
- assert((instance_type)ctrl_data->allocation_type() < max_allocation_type);
- return (instance_type)ctrl_data->allocation_type();
+ assert((instance_type)ctrl_data->alloc_type() < max_allocation_type);
+ return (instance_type)ctrl_data->alloc_type();
}
static std::size_t priv_get_reserved_bytes()
@@ -1311,18 +1307,13 @@
typedef typename MemoryAlgorithm::mutex_family::recursive_mutex_type rmutex;
- #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- scoped_lock<rmutex>
- #else
- detail::move_return<scoped_lock<rmutex> >
- #endif
- priv_get_lock(bool use_lock)
+ scoped_lock<rmutex> priv_get_lock(bool use_lock)
{
scoped_lock<rmutex> local(m_header, defer_lock);
if(use_lock){
local.lock();
}
- return local;
+ return scoped_lock<rmutex>(boost::interprocess::move(local));
}
//!This struct includes needed data and derives from
@@ -1338,6 +1329,7 @@
, m_unique_index(restricted_segment_mngr)
{}
} m_header;
+
/// @endcond
};
Modified: trunk/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- trunk/boost/interprocess/shared_memory_object.hpp (original)
+++ trunk/boost/interprocess/shared_memory_object.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,10 +22,11 @@
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
#include <cstddef>
#include <string>
-#include <cstdio> //std::remove
#include <algorithm>
-#ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+#if defined(BOOST_INTERPROCESS_SYSTEM_V_SHARED_MEMORY_OBJECTS)
+# include <sys/shm.h> //System V shared memory...
+#elif defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
# include <fcntl.h> //O_CREAT, O_*...
# include <sys/mman.h> //shm_xxx
# include <unistd.h> //ftruncate, close
@@ -46,11 +47,12 @@
{
/// @cond
//Non-copyable and non-assignable
- shared_memory_object(const shared_memory_object &);
- shared_memory_object &operator=(const shared_memory_object &);
+ shared_memory_object(shared_memory_object &);
+ shared_memory_object &operator=(shared_memory_object &);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(shared_memory_object)
//!Default constructor. Represents an empty shared_memory_object.
shared_memory_object();
@@ -74,44 +76,22 @@
//!Moves the ownership of "moved"'s shared memory object to *this.
//!After the call, "moved" does not represent any shared memory object.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- shared_memory_object(detail::moved_object<shared_memory_object> moved)
- : m_handle(file_handle_t(detail::invalid_file()))
- { this->swap(moved.get()); }
- #else
- shared_memory_object(shared_memory_object &&moved)
+ shared_memory_object(BOOST_INTERPROCESS_RV_REF(shared_memory_object) moved)
: m_handle(file_handle_t(detail::invalid_file()))
{ this->swap(moved); }
- #endif
//!Moves the ownership of "moved"'s shared memory to *this.
//!After the call, "moved" does not represent any shared memory.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- shared_memory_object &operator=
- (detail::moved_object<shared_memory_object> moved)
+ shared_memory_object &operator=(BOOST_INTERPROCESS_RV_REF(shared_memory_object) moved)
{
- shared_memory_object tmp(moved);
+ shared_memory_object tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
- #else
- shared_memory_object &operator=(shared_memory_object &&moved)
- {
- shared_memory_object tmp(detail::move_impl(moved));
- this->swap(tmp);
- return *this;
- }
- #endif
//!Swaps the shared_memory_objects. Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<shared_memory_object> mother)
- { this->swap(mother.get()); }
- void swap(shared_memory_object &other);
- #else
- void swap(shared_memory_object &&other);
- #endif
+ void swap(shared_memory_object &moved);
//!Erases a shared memory object from the system.
//!Returns false on error. Never throws
@@ -173,11 +153,7 @@
inline bool shared_memory_object::get_size(offset_t &size) const
{ return detail::get_file_size((file_handle_t)m_handle, size); }
-#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
inline void shared_memory_object::swap(shared_memory_object &other)
-#else
-inline void shared_memory_object::swap(shared_memory_object &&other)
-#endif
{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
@@ -185,7 +161,9 @@
}
inline mapping_handle_t shared_memory_object::get_mapping_handle() const
-{ return detail::mapping_handle_from_file_handle(m_handle); }
+{
+ return detail::mapping_handle_from_file_handle(m_handle);
+}
inline mode_t shared_memory_object::get_mode() const
{ return m_mode; }
@@ -229,7 +207,6 @@
throw interprocess_exception(err);
}
- //detail::delete_file_on_reboot_if_possible(shmfile.c_str());
m_mode = mode;
return true;
}
@@ -240,7 +217,7 @@
//Make sure a temporary path is created for shared memory
std::string shmfile;
detail::tmp_filename(filename, shmfile);
- return std::remove(shmfile.c_str()) == 0;
+ return detail::delete_file(shmfile.c_str()) == 0;
}
catch(...){
return false;
@@ -355,14 +332,6 @@
#endif
-//!Trait class to detect if a type is
-//!movable
-template<>
-struct is_movable<shared_memory_object>
-{
- enum { value = true };
-};
-
///@endcond
//!A class that stores the name of a shared memory
Modified: trunk/boost/interprocess/smart_ptr/deleter.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/deleter.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/deleter.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -20,6 +20,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
//!\file
//!Describes the functor to delete objects from the segment.
@@ -35,11 +36,11 @@
class deleter
{
public:
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename SegmentManager::void_pointer, T>::type pointer;
private:
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<pointer, SegmentManager>::type segment_manager_pointer;
segment_manager_pointer mp_mngr;
Modified: trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -24,6 +24,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/checked_delete.hpp>
+#include <boost/pointer_to_other.hpp>
#include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
#include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -41,20 +42,20 @@
class shared_count
{
public:
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, T>::type pointer;
private:
typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, counted_impl>::type counted_impl_ptr;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, sp_counted_base>::type counted_base_ptr;
typedef typename VoidAllocator::template rebind
<counted_impl>::other counted_impl_allocator;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, const Deleter>::type const_deleter_pointer;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, const VoidAllocator>::type const_allocator_pointer;
pointer m_px;
@@ -212,14 +213,14 @@
class weak_count
{
public:
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, T>::type pointer;
private:
typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, counted_impl>::type counted_impl_ptr;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, sp_counted_base>::type counted_base_ptr;
pointer m_px;
Modified: trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -26,6 +26,7 @@
#include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
namespace boost {
@@ -33,6 +34,34 @@
namespace detail {
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an object using a STL allocator.
+template <class Allocator>
+struct scoped_ptr_dealloc_functor
+{
+ typedef typename Allocator::pointer pointer;
+ typedef detail::integral_constant<unsigned,
+ boost::interprocess::version<Allocator>::value> alloc_version;
+ typedef detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef detail::integral_constant<unsigned, 2> allocator_v2;
+
+ private:
+ void priv_deallocate(const typename Allocator::pointer &p, allocator_v1)
+ { m_alloc.deallocate(p, 1); }
+
+ void priv_deallocate(const typename Allocator::pointer &p, allocator_v2)
+ { m_alloc.deallocate_one(p); }
+
+ public:
+ Allocator& m_alloc;
+
+ scoped_ptr_dealloc_functor(Allocator& a)
+ : m_alloc(a) {}
+
+ void operator()(pointer ptr)
+ { if (ptr) priv_deallocate(ptr, alloc_version()); }
+};
+
template<class A, class D>
class sp_counted_impl_pd
: public sp_counted_base
@@ -50,10 +79,10 @@
sp_counted_impl_pd( sp_counted_impl_pd const & );
sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename A::pointer, const D>::type const_deleter_pointer;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename A::pointer, const A>::type const_allocator_pointer;
typedef typename D::pointer pointer;
@@ -73,7 +102,7 @@
{ return const_allocator_pointer(&static_cast<const A&>(*this)); }
void dispose() // nothrow
- { static_cast<D&>(*this)(m_ptr); }
+ { static_cast<D&>(*this)(m_ptr); }
void destroy() // nothrow
{
@@ -83,8 +112,8 @@
BOOST_ASSERT(a_copy == *this);
this_pointer this_ptr (this);
//Do it now!
- scoped_ptr<this_type,
- scoped_ptr_dealloc_functor<this_allocator> > deallocator(this_ptr, a_copy);
+ scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
+ deleter(this_ptr, a_copy);
typedef typename this_allocator::value_type value_type;
detail::get_pointer(this_ptr)->~value_type();
}
Modified: trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,6 +22,7 @@
#include <boost/assert.hpp>
#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
#include <functional> // for std::less
#include <iosfwd> // for std::basic_ostream
@@ -49,7 +50,7 @@
{
public:
//!Provides the type of the internal stored pointer.
- typedef typename detail::pointer_to_other<VoidPointer, T>::type pointer;
+ typedef typename boost::pointer_to_other<VoidPointer, T>::type pointer;
//!Provides the type of the stored pointer.
typedef T element_type;
Modified: trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,6 +19,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/pointer_type.hpp>
#include <boost/assert.hpp>
+#include <boost/pointer_to_other.hpp>
//!\file
//!Describes the smart pointer scoped_ptr
@@ -54,7 +55,7 @@
typedef typename detail::pointer_type<T, Deleter>::type pointer;
//!Provides the type of the internal stored pointer
-// typedef typename detail::pointer_to_other
+// typedef typename boost::pointer_to_other
// <typename Deleter::pointer, T>::type pointer;
//!Constructs a scoped_ptr, storing a copy of p(which can be 0) and d.
Modified: trunk/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/shared_ptr.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -29,6 +29,7 @@
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <boost/static_assert.hpp>
+#include <boost/pointer_to_other.hpp>
#include <algorithm> // for std::swap
#include <functional> // for std::less
@@ -96,18 +97,20 @@
typedef T element_type;
typedef T value_type;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, T>::type pointer;
typedef typename detail::add_reference
<value_type>::type reference;
typedef typename detail::add_reference
<const value_type>::type const_reference;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, const Deleter>::type const_deleter_pointer;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, const VoidAllocator>::type const_allocator_pointer;
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(shared_ptr)
+
//!Constructs an empty shared_ptr.
//!Use_count() == 0 && get()== 0.
shared_ptr()
@@ -122,7 +125,7 @@
{
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
- typedef typename detail::pointer_to_other<pointer, T>::type ParameterPointer;
+ typedef typename boost::pointer_to_other<pointer, T>::type ParameterPointer;
BOOST_STATIC_ASSERT((detail::is_same<pointer, ParameterPointer>::value) ||
(detail::is_pointer<pointer>::value));
detail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, detail::get_pointer(p), detail::get_pointer(p) );
@@ -153,15 +156,9 @@
//!Move-Constructs a shared_ptr that takes ownership of other resource and
//!other is put in default-constructed state.
//!Throws: nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- explicit shared_ptr(detail::moved_object<shared_ptr> other)
- : m_pn()
- { this->swap(other.get()); }
- #else
- explicit shared_ptr(shared_ptr &&other)
+ explicit shared_ptr(BOOST_INTERPROCESS_RV_REF(shared_ptr) other)
: m_pn()
{ this->swap(other); }
- #endif
/// @cond
template<class Y>
@@ -198,19 +195,11 @@
//!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
//!Never throws
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- shared_ptr & operator=(detail::moved_object<shared_ptr> other) // never throws
- {
- this_type(other).swap(*this);
- return *this;
- }
- #else
- shared_ptr & operator=(shared_ptr &&other) // never throws
+ shared_ptr & operator=(BOOST_INTERPROCESS_RV_REF(shared_ptr) other) // never throws
{
this_type(other).swap(*this);
return *this;
}
- #endif
//!This is equivalent to:
//!this_type().swap(*this);
@@ -226,7 +215,7 @@
{
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
- typedef typename detail::pointer_to_other<Pointer, T>::type ParameterPointer;
+ typedef typename boost::pointer_to_other<Pointer, T>::type ParameterPointer;
BOOST_STATIC_ASSERT((detail::is_same<pointer, ParameterPointer>::value) ||
(detail::is_pointer<Pointer>::value));
this_type(p, a, d).swap(*this);
@@ -371,26 +360,6 @@
);
}
-
-/*
-// get_deleter (experimental)
-template<class T, class VoidAllocator, class Deleter>
-typename detail::pointer_to_other<shared_ptr<T, VoidAllocator, Deleter>, Deleter>::type
- get_deleter(shared_ptr<T, VoidAllocator, Deleter> const & p)
-{ return static_cast<Deleter *>(p._internal_get_deleter(typeid(Deleter))); }
-*/
-
-/// @cond
-
-//!This class has move constructor
-template <class T, class VA, class D>
-struct is_movable<boost::interprocess::shared_ptr<T, VA, D> >
-{
- enum { value = true };
-};
-
-/// @endcond
-
} // namespace interprocess
/// @cond
Modified: trunk/boost/interprocess/smart_ptr/unique_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/unique_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/unique_ptr.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -88,6 +88,8 @@
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(unique_ptr)
+
typedef T element_type;
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::type pointer;
@@ -142,7 +144,7 @@
//!
//!After the construction, u no longer owns a pointer.
//![ Note: The deleter constructor can be implemented with
- //!std::detail::forward_impl<D>. -end note ]
+ //! boost::interprocess::forward<D>. -end note ]
//!
//!Postconditions: get() == value u.get() had before the construction.
//!get_deleter() returns a reference to the internally stored deleter which
@@ -150,15 +152,9 @@
//!deleter() and u.get_deleter() both reference the same lvalue deleter.
//!
//!Throws: nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- unique_ptr(detail::moved_object<unique_ptr> u)
- : ptr_(u.get().release(), detail::move_impl(u.get().get_deleter()))
- {}
- #else
- unique_ptr(unique_ptr &&u)
- : ptr_(u.release(), detail::forward_impl<D>(u.get_deleter()))
+ unique_ptr(BOOST_INTERPROCESS_RV_REF(unique_ptr) u)
+ : ptr_(u.release(), boost::interprocess::forward<D>(u.get_deleter()))
{}
- #endif
//!Requires: If D is not a reference type, construction of the deleter
//!D from an rvalue of type E must be well formed
@@ -179,24 +175,8 @@
//!was constructed from u.get_deleter().
//!
//!Throws: nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- template <class U, class E>
- unique_ptr(detail::moved_object<unique_ptr<U, E> > u,
- typename detail::enable_if_c<
- detail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
- detail::is_convertible<E, D>::value &&
- (
- !detail::is_reference<D>::value ||
- detail::is_same<D, E>::value
- )
- ,
- nat
- >::type = nat())
- : ptr_(const_cast<unique_ptr<U,E>&>(u.get()).release(), detail::move_impl(u.get().get_deleter()))
- {}
- #else
template <class U, class E>
- unique_ptr(unique_ptr<U, E> && u,
+ unique_ptr(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(unique_ptr, U, E) u,
typename detail::enable_if_c<
detail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
detail::is_convertible<E, D>::value &&
@@ -207,9 +187,8 @@
,
nat
>::type = nat())
- : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), detail::forward_impl<D>(u.get_deleter()))
+ : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), boost::interprocess::move<D>(u.get_deleter()))
{}
- #endif
//!Effects: If get() == 0 there are no effects. Otherwise get_deleter()(get()).
//!
@@ -230,21 +209,12 @@
//!Returns: *this.
//!
//!Throws: nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- unique_ptr& operator=(detail::moved_object<unique_ptr> u)
- {
- reset(u.get().release());
- ptr_.second() = detail::move_impl(u.get().get_deleter());
- return *this;
- }
- #else
- unique_ptr& operator=(unique_ptr && u)
+ unique_ptr& operator=(BOOST_INTERPROCESS_RV_REF(unique_ptr) u)
{
reset(u.release());
- ptr_.second() = detail::move_impl(u.get_deleter());
+ ptr_.second() = boost::interprocess::move(u.get_deleter());
return *this;
}
- #endif
//!Requires: Assignment of the deleter D from an rvalue D must not
//!throw an exception. U* must be implicitly convertible to T*.
@@ -261,21 +231,12 @@
//!
//!Throws: nothing.
template <class U, class E>
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- unique_ptr& operator=(detail::moved_object<unique_ptr<U, E> > mu)
- {
- reset(mu.get().release());
- ptr_.second() = detail::move_impl(mu.get().get_deleter());
- return *this;
- }
- #else
- unique_ptr& operator=(unique_ptr<U, E> && u)
+ unique_ptr& operator=(BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(unique_ptr, U, E) u)
{
reset(u.release());
- ptr_.second() = detail::move_impl(u.get_deleter());
+ ptr_.second() = boost::interprocess::move(u.get_deleter());
return *this;
}
- #endif
//!Assigns from the literal 0 or NULL.
//!
@@ -359,23 +320,14 @@
//!Effects: The stored pointers of this and u are exchanged.
//! The stored deleters are swapped (unqualified).
//!Throws: nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
void swap(unique_ptr& u)
{ ptr_.swap(u.ptr_); }
- void swap(detail::moved_object<unique_ptr> mu)
- { ptr_.swap(mu.get().ptr_); }
- #else
- void swap(unique_ptr&&u)
- { ptr_.swap(u.ptr_); }
- #endif
-
/// @cond
private:
boost::compressed_pair<pointer, D> ptr_;
- //This private constructor avoids moving from non-const lvalues
- unique_ptr(const unique_ptr&);
+ unique_ptr(unique_ptr&);
template <class U, class E> unique_ptr(unique_ptr<U, E>&);
template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
@@ -570,16 +522,6 @@
bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
{ return x.get() >= y.get(); }
-/// @cond
-
-//!This class has move constructor
-template <class T, class D>
-struct is_movable<unique_ptr<T, D> >
-{
- enum { value = true };
-};
-/// @endcond
-
//!Returns the type of a unique pointer
//!of type T with boost::interprocess::deleter deleter
@@ -597,20 +539,11 @@
//!with boost::interproces::deleter from a pointer
//!of type T that has been allocated in the passed managed segment
template<class T, class ManagedMemory>
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-inline typename detail::return_type
- <typename managed_unique_ptr<T, ManagedMemory>::type
- >::type
-#else
-typename managed_unique_ptr<T, ManagedMemory>::type
-#endif
+inline typename managed_unique_ptr<T, ManagedMemory>::type
make_managed_unique_ptr(T *constructed_object, ManagedMemory &managed_memory)
{
- typename managed_unique_ptr<T, ManagedMemory>::type to_return
- ( constructed_object
- , managed_memory.template get_deleter<T>()
- );
- return to_return;
+ return typename managed_unique_ptr<T, ManagedMemory>::type
+ (constructed_object, managed_memory.template get_deleter<T>());
}
} //namespace interprocess{
Modified: trunk/boost/interprocess/smart_ptr/weak_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/weak_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/weak_ptr.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,6 +22,7 @@
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/smart_ptr/deleter.hpp>
+#include <boost/pointer_to_other.hpp>
//!\file
//!Describes the smart pointer weak_ptr.
@@ -53,7 +54,7 @@
private:
// Borland 5.5.1 specific workarounds
typedef weak_ptr<T, A, D> this_type;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<typename A::pointer, T>::type pointer;
typedef typename detail::add_reference
<T>::type reference;
Modified: trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -94,11 +94,11 @@
InternalLock lock;
if(tout_enabled){
InternalLock dummy(m_enter_mut, abs_time);
- lock = detail::move_impl(dummy);
+ lock = boost::interprocess::move(dummy);
}
else{
InternalLock dummy(m_enter_mut);
- lock = detail::move_impl(dummy);
+ lock = boost::interprocess::move(dummy);
}
if(!lock)
@@ -161,15 +161,18 @@
InternalLock lock;
if(tout_enabled){
InternalLock dummy(m_check_mut, abs_time);
- lock = detail::move_impl(dummy);
+ lock = boost::interprocess::move(dummy);
}
else{
InternalLock dummy(m_check_mut);
- lock = detail::move_impl(dummy);
+ lock = boost::interprocess::move(dummy);
}
- if(!lock)
- return false;
+ if(!lock){
+ timed_out = true;
+ unlock_enter_mut = true;
+ break;
+ }
//---------------------------------------------------------------
boost::uint32_t result = detail::atomic_cas32
(const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ONE);
Modified: trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -39,8 +39,11 @@
inline void interprocess_recursive_mutex::lock()
{
- detail::OS_systemwide_thread_id_t th_id = detail::get_current_systemwide_thread_id();
- if(detail::equal_systemwide_thread_id(th_id, m_nOwner)){
+ typedef detail::OS_systemwide_thread_id_t handle_t;
+ const handle_t thr_id(detail::get_current_systemwide_thread_id());
+ handle_t old_id;
+ detail::systemwide_thread_id_copy(m_nOwner, old_id);
+ if(detail::equal_systemwide_thread_id(thr_id , old_id)){
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception();
@@ -49,15 +52,18 @@
}
else{
m_mutex.lock();
- m_nOwner = th_id;
+ detail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
}
}
inline bool interprocess_recursive_mutex::try_lock()
{
- detail::OS_systemwide_thread_id_t th_id = detail::get_current_systemwide_thread_id();
- if(detail::equal_systemwide_thread_id(th_id, m_nOwner)) { // we own it
+ typedef detail::OS_systemwide_thread_id_t handle_t;
+ handle_t thr_id(detail::get_current_systemwide_thread_id());
+ handle_t old_id;
+ detail::systemwide_thread_id_copy(m_nOwner, old_id);
+ if(detail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception();
@@ -66,7 +72,7 @@
return true;
}
if(m_mutex.try_lock()){
- m_nOwner = th_id;
+ detail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
return true;
}
@@ -75,12 +81,15 @@
inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
+ typedef detail::OS_systemwide_thread_id_t handle_t;
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
- detail::OS_systemwide_thread_id_t th_id = detail::get_current_systemwide_thread_id();
- if(detail::equal_systemwide_thread_id(th_id, m_nOwner)) { // we own it
+ const handle_t thr_id(detail::get_current_systemwide_thread_id());
+ handle_t old_id;
+ detail::systemwide_thread_id_copy(m_nOwner, old_id);
+ if(detail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception();
@@ -89,7 +98,7 @@
return true;
}
if(m_mutex.timed_lock(abs_time)){
- m_nOwner = th_id;
+ detail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
return true;
}
@@ -98,10 +107,16 @@
inline void interprocess_recursive_mutex::unlock()
{
- assert(detail::equal_systemwide_thread_id(detail::get_current_systemwide_thread_id(), m_nOwner));
+ typedef detail::OS_systemwide_thread_id_t handle_t;
+ handle_t old_id;
+ detail::systemwide_thread_id_copy(m_nOwner, old_id);
+ const handle_t thr_id(detail::get_current_systemwide_thread_id());
+ (void)old_id;
+ assert(detail::equal_systemwide_thread_id(thr_id, old_id));
--m_nLockCount;
if(!m_nLockCount){
- m_nOwner = detail::get_invalid_systemwide_thread_id();
+ const handle_t new_id(detail::get_invalid_systemwide_thread_id());
+ detail::systemwide_thread_id_copy(new_id, m_nOwner);
m_mutex.unlock();
}
}
Modified: trunk/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/file_lock.hpp (original)
+++ trunk/boost/interprocess/sync/file_lock.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -29,19 +29,6 @@
namespace boost {
namespace interprocess {
-///@cond
-
-class file_lock;
-
-//!Trait class to detect if a type is
-//!movable
-template<>
-struct is_movable<file_lock>
-{
- enum { value = true };
-};
-
-///@endcond
//!A file lock, is a mutual exclusion utility similar to a mutex using a
//!file. A file lock has sharable and exclusive locking capabilities and
@@ -56,6 +43,7 @@
file_lock &operator=(const file_lock &);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(file_lock)
//!Constructs an empty file mapping.
//!Does not throw
@@ -70,28 +58,16 @@
//!Moves the ownership of "moved"'s file mapping object to *this.
//!After the call, "moved" does not represent any file mapping object.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- file_lock(detail::moved_object<file_lock> moved)
- : m_file_hnd(file_handle_t(detail::invalid_file()))
- { this->swap(moved.get()); }
- #else
- file_lock(file_lock &&moved)
+ file_lock(BOOST_INTERPROCESS_RV_REF(file_lock) moved)
: m_file_hnd(file_handle_t(detail::invalid_file()))
{ this->swap(moved); }
- #endif
//!Moves the ownership of "moved"'s file mapping to *this.
//!After the call, "moved" does not represent any file mapping.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- file_lock &operator=(detail::moved_object<file_lock> m_other)
- {
- file_lock &moved = m_other.get();
- #else
- file_lock &operator=(file_lock &&moved)
+ file_lock &operator=(BOOST_INTERPROCESS_RV_REF(file_lock) moved)
{
- #endif
- file_lock tmp(detail::move_impl(moved));
+ file_lock tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -101,13 +77,7 @@
//!Swaps two file_locks.
//!Does not throw.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<file_lock> mother)
- { this->swap(mother.get()); }
void swap(file_lock &other)
- #else
- void swap(file_lock &&other)
- #endif
{
file_handle_t tmp = m_file_hnd;
m_file_hnd = other.m_file_hnd;
Modified: trunk/boost/interprocess/sync/interprocess_barrier.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_barrier.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_barrier.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -26,6 +26,8 @@
#ifndef BOOST_INTERPROCESS_BARRIER_HPP
#define BOOST_INTERPROCESS_BARRIER_HPP
+/// @cond
+
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
@@ -48,6 +50,8 @@
# include <boost/interprocess/exceptions.hpp>
+/// @endcond
+
namespace boost {
namespace interprocess {
Modified: trunk/boost/interprocess/sync/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_condition.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -15,6 +15,8 @@
# pragma once
#endif
+/// @cond
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
@@ -38,6 +40,8 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
+/// @endcond
+
//!\file
//!Describes process-shared variables interprocess_condition class
Modified: trunk/boost/interprocess/sync/interprocess_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_mutex.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,6 +27,8 @@
#ifndef BOOST_INTERPROCESS_MUTEX_HPP
#define BOOST_INTERPROCESS_MUTEX_HPP
+/// @cond
+
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
@@ -48,6 +50,8 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
+/// @endcond
+
//!\file
//!Describes a mutex class that can be placed in memory shared by
//!several processes.
@@ -110,7 +114,7 @@
volatile boost::uint32_t m_s;
#elif defined(BOOST_INTERPROCESS_USE_POSIX)
pthread_mutex_t m_mut;
- #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ #endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
/// @endcond
};
Modified: trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,6 +27,8 @@
#ifndef BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP
#define BOOST_INTERPROCESS_RECURSIVE_MUTEX_HPP
+/// @cond
+
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
@@ -50,6 +52,8 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
+/// @endcond
+
//!\file
//!Describes interprocess_recursive_mutex and shared_recursive_try_mutex classes
@@ -106,10 +110,10 @@
#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
interprocess_mutex m_mutex;
unsigned int m_nLockCount;
- detail::OS_systemwide_thread_id_t m_nOwner;
+ volatile detail::OS_systemwide_thread_id_t m_nOwner;
#else //#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
pthread_mutex_t m_mut;
- #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+ #endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
/// @endcond
};
Modified: trunk/boost/interprocess/sync/interprocess_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_semaphore.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -11,6 +11,8 @@
#ifndef BOOST_INTERPROCESS_SEMAPHORE_HPP
#define BOOST_INTERPROCESS_SEMAPHORE_HPP
+/// @cond
+
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
@@ -22,7 +24,7 @@
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
- (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES))
+ (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES))
#include <fcntl.h> //O_CREAT, O_*...
#include <unistd.h> //close
#include <string> //std::string
@@ -39,6 +41,8 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
+/// @endcond
+
//!\file
//!Describes a interprocess_semaphore class for inter-process synchronization
Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp (original)
+++ trunk/boost/interprocess/sync/named_condition.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,6 +17,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
@@ -24,6 +26,7 @@
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
+#include <boost/interprocess/sync/named_mutex.hpp>
#if defined BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
@@ -85,7 +88,7 @@
//!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!Releases the lock on the named_mutex object associated with lock, blocks
//!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
@@ -96,7 +99,7 @@
template <typename L, typename Pr>
void wait(L& lock, Pr pred);
- //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!Releases the lock on the named_mutex object associated with lock, blocks
//!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), or until time abs_time is reached,
//!and then reacquires the lock.
@@ -148,7 +151,10 @@
template <class Lock>
void do_wait(Lock& lock)
- {
+ {
+ //named_condition only works with named_mutex
+ BOOST_STATIC_ASSERT((detail::is_same<typename Lock::mutex_type, named_mutex>::value == true));
+
//lock internal before unlocking external to avoid race with a notifier
scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
lock_inverter<Lock> inverted_lock(lock);
@@ -163,6 +169,8 @@
template <class Lock>
bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time)
{
+ //named_condition only works with named_mutex
+ BOOST_STATIC_ASSERT((detail::is_same<typename Lock::mutex_type, named_mutex>::value == true));
//lock internal before unlocking external to avoid race with a notifier
scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
if(!internal_lock) return false;
Modified: trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp (original)
+++ trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -20,7 +20,7 @@
#include <semaphore.h>
#ifdef SEM_FAILED
-#define BOOST_INTERPROCESS_POSIX_SEM_FAILED SEM_FAILED
+#define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(SEM_FAILED))
#else
#define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))
#endif
Modified: trunk/boost/interprocess/sync/scoped_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/scoped_lock.hpp (original)
+++ trunk/boost/interprocess/sync/scoped_lock.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,8 +22,11 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/sync/lock_options.hpp>
#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -33,11 +36,6 @@
namespace boost {
namespace interprocess {
-template<class M>
-class sharable_lock;
-
-template<class M>
-class upgradable_lock;
//!scoped_lock is meant to carry out the tasks for locking, unlocking, try-locking
//!and timed-locking (recursive or not) for the Mutex. The Mutex need not supply all
@@ -55,11 +53,13 @@
/// @cond
private:
typedef scoped_lock<Mutex> this_type;
- scoped_lock(scoped_lock const&);
- scoped_lock& operator= (scoped_lock const&);
+ scoped_lock(scoped_lock&);
+ scoped_lock& operator= (scoped_lock&);
typedef bool this_type::*unspecified_bool_type;
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(scoped_lock)
+
typedef Mutex mutex_type;
//!Effects: Default constructs a scoped_lock.
@@ -122,18 +122,12 @@
//! to thisscoped_lock with no blocking. If the scop scoped_lock does not
//! own the mutex, then neither will this scoped_lock. Only a moved
//! scoped_lock's will match this signature. An non-moved scoped_lock
- //! can be moved with the expression: "detail::move_impl(lock);". This
+ //! can be moved with the expression: "boost::interprocess::move(lock);". This
//! constructor does not alter the state of the mutex, only potentially
//! who owns it.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- scoped_lock(detail::moved_object<scoped_lock<Mutex> > scop)
- : mp_mutex(0), m_locked(scop.get().owns())
- { mp_mutex = scop.get().release(); }
- #else
- scoped_lock(scoped_lock &&scop)
+ scoped_lock(BOOST_INTERPROCESS_RV_REF(scoped_lock) scop)
: mp_mutex(0), m_locked(scop.owns())
{ mp_mutex = scop.release(); }
- #endif
//!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the
//! referenced mutex. upgr.release() is called.
@@ -144,22 +138,12 @@
//! unlocking upgr. If upgr is unlocked, then this scoped_lock will be
//! unlocked as well. Only a moved upgradable_lock's will match this
//! signature. An non-moved upgradable_lock can be moved with
- //! the expression: "detail::move_impl(lock);" This constructor may block if
+ //! the expression: "boost::interprocess::move(lock);" This constructor may block if
//! other threads hold a sharable_lock on this mutex (sharable_lock's can
//! share ownership with an upgradable_lock).
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr)
- : mp_mutex(0), m_locked(false)
- {
- upgradable_lock<mutex_type> &u_lock = upgr.get();
- if(u_lock.owns()){
- u_lock.mutex()->unlock_upgradable_and_lock();
- m_locked = true;
- }
- mp_mutex = u_lock.release();
- }
- #else
- scoped_lock(upgradable_lock<Mutex> &&upgr)
+ template<class T>
+ explicit scoped_lock(BOOST_INTERPROCESS_RV_REF(upgradable_lock<T>) upgr
+ , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -169,7 +153,6 @@
}
mp_mutex = u_lock.release();
}
- #endif
//!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the
//!referenced mutex:
@@ -185,25 +168,10 @@
//! "read lock" to a "write lock". If the "read lock" isn't held in the
//! first place, the mutex merely changes type to an unlocked "write lock".
//! If the "read lock" is held, then mutex transfer occurs only if it can
- //! do so in a non-blocking manner.*/
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
- ,try_to_lock_type)
- : mp_mutex(0), m_locked(false)
- {
- upgradable_lock<mutex_type> &u_lock = upgr.get();
- if(u_lock.owns()){
- if((m_locked = u_lock.mutex()->try_unlock_upgradable_and_lock()) == true){
- mp_mutex = u_lock.release();
- }
- }
- else{
- u_lock.release();
- }
- }
- #else
- scoped_lock(upgradable_lock<Mutex> &&upgr
- ,try_to_lock_type)
+ //! do so in a non-blocking manner.
+ template<class T>
+ scoped_lock(BOOST_INTERPROCESS_RV_REF(upgradable_lock<T>) upgr, try_to_lock_type
+ , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -216,7 +184,6 @@
u_lock.release();
}
}
- #endif
//!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)
//! on the referenced mutex:
@@ -232,24 +199,9 @@
//! "write lock". If the "read lock" isn't held in the first place, the mutex
//! merely changes type to an unlocked "write lock". If the "read lock" is held,
//! then mutex transfer occurs only if it can do so in a non-blocking manner.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
- ,boost::posix_time::ptime &abs_time)
- : mp_mutex(0), m_locked(false)
- {
- upgradable_lock<mutex_type> &u_lock = upgr.get();
- if(u_lock.owns()){
- if((m_locked = u_lock.mutex()->timed_unlock_upgradable_and_lock(abs_time)) == true){
- mp_mutex = u_lock.release();
- }
- }
- else{
- u_lock.release();
- }
- }
- #else
- scoped_lock(upgradable_lock<Mutex> &&upgr
- ,boost::posix_time::ptime &abs_time)
+ template<class T>
+ scoped_lock(BOOST_INTERPROCESS_RV_REF(upgradable_lock<T>) upgr, boost::posix_time::ptime &abs_time
+ , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -262,7 +214,6 @@
u_lock.release();
}
}
- #endif
//!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the
//!referenced mutex.
@@ -279,24 +230,9 @@
//! first place, the mutex merely changes type to an unlocked "write lock".
//! If the "read lock" is held, then mutex transfer occurs only if it can
//! do so in a non-blocking manner.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- scoped_lock(detail::moved_object<sharable_lock<Mutex> > shar
- ,try_to_lock_type)
- : mp_mutex(0), m_locked(false)
- {
- sharable_lock<mutex_type> &s_lock = shar.get();
- if(s_lock.owns()){
- if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock()) == true){
- mp_mutex = s_lock.release();
- }
- }
- else{
- s_lock.release();
- }
- }
- #else
- scoped_lock(sharable_lock<Mutex> &&shar
- ,try_to_lock_type)
+ template<class T>
+ scoped_lock(BOOST_INTERPROCESS_RV_REF(sharable_lock<T>) shar, try_to_lock_type
+ , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
sharable_lock<mutex_type> &s_lock = shar;
@@ -309,7 +245,6 @@
s_lock.release();
}
}
- #endif
//!Effects: if (owns()) mp_mutex->unlock().
//!Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
@@ -325,17 +260,7 @@
//! the same mutex before the assignment. In this case, this will own the
//! mutex after the assignment (and scop will not), but the mutex's lock
//! count will be decremented by one.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- scoped_lock &operator=(detail::moved_object<scoped_lock> scop)
- {
- if(this->owns())
- this->unlock();
- m_locked = scop.get().owns();
- mp_mutex = scop.get().release();
- return *this;
- }
- #else
- scoped_lock &operator=(scoped_lock &&scop)
+ scoped_lock &operator=(BOOST_INTERPROCESS_RV_REF(scoped_lock) scop)
{
if(this->owns())
this->unlock();
@@ -343,7 +268,6 @@
mp_mutex = scop.release();
return *this;
}
- #endif
//!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
//! exception. Calls lock() on the referenced mutex.
@@ -429,19 +353,11 @@
//!Effects: Swaps state with moved lock.
//!Throws: Nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<scoped_lock<mutex_type> > other)
- {
- std::swap(mp_mutex, other.get().mp_mutex);
- std::swap(m_locked, other.get().m_locked);
- }
- #else
- void swap(scoped_lock<mutex_type> &&other)
+ void swap( scoped_lock<mutex_type> &other)
{
std::swap(mp_mutex, other.mp_mutex);
std::swap(m_locked, other.m_locked);
}
- #endif
/// @cond
private:
@@ -450,16 +366,6 @@
/// @endcond
};
-/// @cond
-
-//!This class is movable
-template <class M>
-struct is_movable<scoped_lock<M> >
-{
- enum { value = true };
-};
-/// @endcond
-
} // namespace interprocess
} // namespace boost
Modified: trunk/boost/interprocess/sync/sharable_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/sharable_lock.hpp (original)
+++ trunk/boost/interprocess/sync/sharable_lock.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,10 +22,12 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/sync/lock_options.hpp>
#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/move.hpp>
-//Ig#include <boost/utility.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
//!\file
@@ -35,11 +37,6 @@
namespace boost {
namespace interprocess {
-template<class M>
-class scoped_lock;
-
-template<class M>
-class upgradable_lock;
//!sharable_lock is meant to carry out the tasks for sharable-locking
//!(such as read-locking), unlocking, try-sharable-locking and timed-sharable-locking
@@ -57,13 +54,14 @@
/// @cond
private:
typedef sharable_lock<SharableMutex> this_type;
- sharable_lock(sharable_lock const&);
- explicit sharable_lock(scoped_lock<mutex_type> const&);
+ sharable_lock(sharable_lock&);
+ explicit sharable_lock(scoped_lock<mutex_type>&);
typedef bool this_type::*unspecified_bool_type;
- sharable_lock& operator=(sharable_lock const&);
- sharable_lock& operator=(scoped_lock<mutex_type> const&);
+ sharable_lock& operator=(sharable_lock&);
+ sharable_lock& operator=(scoped_lock<mutex_type>&);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(sharable_lock)
//!Effects: Default constructs a sharable_lock.
//!Postconditions: owns() == false and mutex() == 0.
@@ -127,17 +125,11 @@
//! sharable_lock with no blocking. If the upgr sharable_lock does not own the mutex, then
//! neither will this sharable_lock. Only a moved sharable_lock's will match this
//! signature. An non-moved sharable_lock can be moved with the expression:
- //! "detail::move_impl(lock);". This constructor does not alter the state of the mutex,
+ //! "boost::interprocess::move(lock);". This constructor does not alter the state of the mutex,
//! only potentially who owns it.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- sharable_lock(detail::moved_object<sharable_lock<mutex_type> > upgr)
- : mp_mutex(0), m_locked(upgr.get().owns())
- { mp_mutex = upgr.get().release(); }
- #else
- sharable_lock(sharable_lock<mutex_type> &&upgr)
+ sharable_lock(BOOST_INTERPROCESS_RV_REF(sharable_lock<mutex_type>) upgr)
: mp_mutex(0), m_locked(upgr.owns())
{ mp_mutex = upgr.release(); }
- #endif
//!Effects: If upgr.owns() then calls unlock_upgradable_and_lock_sharable() on the
//! referenced mutex.
@@ -147,20 +139,10 @@
//!Notes: If upgr is locked, this constructor will lock this sharable_lock while
//! unlocking upgr. Only a moved sharable_lock's will match this
//! signature. An non-moved upgradable_lock can be moved with the expression:
- //! "detail::move_impl(lock);".*/
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- sharable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
- : mp_mutex(0), m_locked(false)
- {
- upgradable_lock<mutex_type> &u_lock = upgr.get();
- if(u_lock.owns()){
- u_lock.mutex()->unlock_upgradable_and_lock_sharable();
- m_locked = true;
- }
- mp_mutex = u_lock.release();
- }
- #else
- sharable_lock(upgradable_lock<mutex_type> &&upgr)
+ //! "boost::interprocess::move(lock);".*/
+ template<class T>
+ sharable_lock(BOOST_INTERPROCESS_RV_REF(upgradable_lock<T>) upgr
+ , typename detail::enable_if< detail::is_same<T, SharableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -170,7 +152,6 @@
}
mp_mutex = u_lock.release();
}
- #endif
//!Effects: If scop.owns() then calls unlock_and_lock_sharable() on the
//! referenced mutex.
@@ -181,20 +162,10 @@
//! to a sharable-ownership of this sharable_lock.
//! Only a moved scoped_lock's will match this
//! signature. An non-moved scoped_lock can be moved with the expression:
- //! "detail::move_impl(lock);".*/
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- sharable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
- : mp_mutex(0), m_locked(false)
- {
- scoped_lock<mutex_type> &e_lock = scop.get();
- if(e_lock.owns()){
- e_lock.mutex()->unlock_and_lock_sharable();
- m_locked = true;
- }
- mp_mutex = e_lock.release();
- }
- #else
- sharable_lock(scoped_lock<mutex_type> &&scop)
+ //! "boost::interprocess::move(lock);".
+ template<class T>
+ sharable_lock(BOOST_INTERPROCESS_RV_REF(scoped_lock<T>) scop
+ , typename detail::enable_if< detail::is_same<T, SharableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
scoped_lock<mutex_type> &e_lock = scop;
@@ -204,7 +175,6 @@
}
mp_mutex = e_lock.release();
}
- #endif
//!Effects: if (owns()) mp_mutex->unlock_sharable().
//!Notes: The destructor behavior ensures that the mutex lock is not leaked.
@@ -221,17 +191,7 @@
//!Notes: With a recursive mutex it is possible that both this and upgr own the mutex
//! before the assignment. In this case, this will own the mutex after the assignment
//! (and upgr will not), but the mutex's lock count will be decremented by one.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- sharable_lock &operator=(detail::moved_object<sharable_lock<mutex_type> > upgr)
- {
- if(this->owns())
- this->unlock();
- m_locked = upgr.get().owns();
- mp_mutex = upgr.get().release();
- return *this;
- }
- #else
- sharable_lock &operator=(sharable_lock<mutex_type> &&upgr)
+ sharable_lock &operator=(BOOST_INTERPROCESS_RV_REF(sharable_lock<mutex_type>) upgr)
{
if(this->owns())
this->unlock();
@@ -239,7 +199,6 @@
mp_mutex = upgr.release();
return *this;
}
- #endif
//!Effects: If mutex() == 0 or already locked, throws a lock_exception()
//! exception. Calls lock_sharable() on the referenced mutex.
@@ -328,19 +287,11 @@
//!Effects: Swaps state with moved lock.
//!Throws: Nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<sharable_lock<mutex_type> > other)
- {
- std::swap(mp_mutex, other.get().mp_mutex);
- std::swap(m_locked, other.get().m_locked);
- }
- #else
- void swap(sharable_lock<mutex_type> &&other)
+ void swap(sharable_lock<mutex_type> &other)
{
std::swap(mp_mutex, other.mp_mutex);
std::swap(m_locked, other.m_locked);
}
- #endif
/// @cond
private:
@@ -349,16 +300,6 @@
/// @endcond
};
-/// @cond
-
-//!This class is movable
-template <class M>
-struct is_movable<sharable_lock<M> >
-{
- enum { value = true };
-};
-/// @endcond
-
} // namespace interprocess
} // namespace boost
Modified: trunk/boost/interprocess/sync/upgradable_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/upgradable_lock.hpp (original)
+++ trunk/boost/interprocess/sync/upgradable_lock.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,7 +22,11 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/sync/lock_options.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -34,12 +38,6 @@
namespace boost {
namespace interprocess {
-template<class M>
-class scoped_lock;
-
-template<class M>
-class sharable_lock;
-
//!upgradable_lock is meant to carry out the tasks for read-locking, unlocking,
//!try-read-locking and timed-read-locking (recursive or not) for the Mutex.
//!Additionally the upgradable_lock can transfer ownership to a scoped_lock
@@ -57,13 +55,14 @@
/// @cond
private:
typedef upgradable_lock<UpgradableMutex> this_type;
- upgradable_lock(upgradable_lock const&);
- explicit upgradable_lock(scoped_lock<mutex_type> const&);
+ upgradable_lock(upgradable_lock&);
+ explicit upgradable_lock(scoped_lock<mutex_type>&);
typedef bool this_type::*unspecified_bool_type;
- upgradable_lock& operator=(upgradable_lock const&);
- upgradable_lock& operator=(scoped_lock<mutex_type> const&);
+ upgradable_lock& operator=(upgradable_lock&);
+ upgradable_lock& operator=(scoped_lock<mutex_type>&);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(upgradable_lock)
//!Effects: Default constructs a upgradable_lock.
//!Postconditions: owns() == false and mutex() == 0.
@@ -121,17 +120,11 @@
//! while unlocking upgr. If upgr is unlocked, then this upgradable_lock will
//! be unlocked as well. Only a moved upgradable_lock's will match this
//! signature. An non-moved upgradable_lock can be moved with the
- //! expression: "detail::move_impl(lock);". This constructor does not alter the
+ //! expression: "boost::interprocess::move(lock);". This constructor does not alter the
//! state of the mutex, only potentially who owns it.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- upgradable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
- : mp_mutex(0), m_locked(upgr.get().owns())
- { mp_mutex = upgr.get().release(); }
- #else
- upgradable_lock(upgradable_lock<mutex_type> &&upgr)
+ upgradable_lock(BOOST_INTERPROCESS_RV_REF(upgradable_lock<mutex_type>) upgr)
: mp_mutex(0), m_locked(upgr.owns())
{ mp_mutex = upgr.release(); }
- #endif
//!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
//!Postconditions: mutex() == the value scop.mutex() had before the construction.
@@ -141,20 +134,10 @@
//! to an upgradable-ownership of this upgradable_lock.
//! Only a moved sharable_lock's will match this
//! signature. An non-moved sharable_lock can be moved with the
- //! expression: "detail::move_impl(lock);".
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- upgradable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
- : mp_mutex(0), m_locked(false)
- {
- scoped_lock<mutex_type> &u_lock = scop.get();
- if(u_lock.owns()){
- u_lock.mutex()->unlock_and_lock_upgradable();
- m_locked = true;
- }
- mp_mutex = u_lock.release();
- }
- #else
- upgradable_lock(scoped_lock<mutex_type> &&scop)
+ //! expression: "boost::interprocess::move(lock);".
+ template<class T>
+ upgradable_lock(BOOST_INTERPROCESS_RV_REF(scoped_lock<T>) scop
+ , typename detail::enable_if< detail::is_same<T, UpgradableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
scoped_lock<mutex_type> &u_lock = scop;
@@ -164,7 +147,6 @@
}
mp_mutex = u_lock.release();
}
- #endif
//!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable()
//! on the referenced mutex.
@@ -181,24 +163,9 @@
//! in the first place, the mutex merely changes type to an unlocked
//! "upgradable lock". If the "read lock" is held, then mutex transfer
//! occurs only if it can do so in a non-blocking manner.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- upgradable_lock( detail::moved_object<sharable_lock<mutex_type> > shar
- , try_to_lock_type)
- : mp_mutex(0), m_locked(false)
- {
- sharable_lock<mutex_type> &s_lock = shar.get();
- if(s_lock.owns()){
- if((m_locked = s_lock.mutex()->try_unlock_sharable_and_lock_upgradable()) == true){
- mp_mutex = s_lock.release();
- }
- }
- else{
- s_lock.release();
- }
- }
- #else
- upgradable_lock( sharable_lock<mutex_type> &&shar
- , try_to_lock_type)
+ template<class T>
+ upgradable_lock( BOOST_INTERPROCESS_RV_REF(sharable_lock<T>) shar, try_to_lock_type
+ , typename detail::enable_if< detail::is_same<T, UpgradableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
sharable_lock<mutex_type> &s_lock = shar;
@@ -211,7 +178,6 @@
s_lock.release();
}
}
- #endif
//!Effects: if (owns()) m_->unlock_upgradable().
//!Notes: The destructor behavior ensures that the mutex lock is not leaked.
@@ -229,17 +195,7 @@
//! mutex before the assignment. In this case, this will own the mutex
//! after the assignment (and upgr will not), but the mutex's upgradable lock
//! count will be decremented by one.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- upgradable_lock &operator=(detail::moved_object<upgradable_lock<mutex_type> > upgr)
- {
- if(this->owns())
- this->unlock();
- m_locked = upgr.get().owns();
- mp_mutex = upgr.get().release();
- return *this;
- }
- #else
- upgradable_lock &operator=(upgradable_lock<mutex_type> &&upgr)
+ upgradable_lock &operator=(BOOST_INTERPROCESS_RV_REF(upgradable_lock) upgr)
{
if(this->owns())
this->unlock();
@@ -247,7 +203,6 @@
mp_mutex = upgr.release();
return *this;
}
- #endif
//!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
//! exception. Calls lock_upgradable() on the referenced mutex.
@@ -336,19 +291,11 @@
//!Effects: Swaps state with moved lock.
//!Throws: Nothing.
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- void swap(detail::moved_object<upgradable_lock<mutex_type> > other)
- {
- std::swap(mp_mutex, other.get().mp_mutex);
- std::swap(m_locked, other.get().m_locked);
- }
- #else
- void swap(upgradable_lock<mutex_type> &&other)
+ void swap(upgradable_lock<mutex_type> &other)
{
std::swap(mp_mutex, other.mp_mutex);
std::swap(m_locked, other.m_locked);
}
- #endif
/// @cond
private:
@@ -357,16 +304,6 @@
/// @endcond
};
-/// @cond
-
-//!This class is movable
-template <class M>
-struct is_movable<upgradable_lock<M> >
-{
- enum { value = true };
-};
-/// @endcond
-
} // namespace interprocess
} // namespace boost
Modified: trunk/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/windows_shared_memory.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -15,7 +15,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/detail/workaround.hpp>
-#if !defined(BOOST_WINDOWS) || defined(BOOST_DISABLE_WIN32)
+#if !defined(BOOST_INTERPROCESS_WINDOWS)
#error "This header can only be used in Windows operating systems"
#endif
@@ -51,11 +51,12 @@
{
/// @cond
//Non-copyable and non-assignable
- windows_shared_memory(const windows_shared_memory &);
- windows_shared_memory &operator=(const windows_shared_memory &);
+ windows_shared_memory(windows_shared_memory &);
+ windows_shared_memory &operator=(windows_shared_memory &);
/// @endcond
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(windows_shared_memory)
//!Default constructor.
//!Represents an empty windows_shared_memory.
@@ -81,26 +82,15 @@
//!Moves the ownership of "moved"'s shared memory object to *this.
//!After the call, "moved" does not represent any shared memory object.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- windows_shared_memory
- (detail::moved_object<windows_shared_memory> moved)
- { this->swap(moved.get()); }
- #else
- windows_shared_memory(windows_shared_memory &&moved)
+ windows_shared_memory(BOOST_INTERPROCESS_RV_REF(windows_shared_memory) moved)
{ this->swap(moved); }
- #endif
//!Moves the ownership of "moved"'s shared memory to *this.
//!After the call, "moved" does not represent any shared memory.
//!Does not throw
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
- windows_shared_memory &operator=
- (detail::moved_object<windows_shared_memory> moved)
- #else
- windows_shared_memory &operator=(windows_shared_memory &&moved)
- #endif
+ windows_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(windows_shared_memory) moved)
{
- windows_shared_memory tmp(detail::move_impl(moved));
+ windows_shared_memory tmp(boost::interprocess::move(moved));
this->swap(tmp);
return *this;
}
@@ -232,14 +222,6 @@
}
}
-//!Trait class to detect if a type is
-//!movable
-template<>
-struct is_movable<windows_shared_memory>
-{
- static const bool value = true;
-};
-
///@endcond
} //namespace interprocess {
Modified: trunk/boost/intrusive/detail/ebo_functor_holder.hpp
==============================================================================
--- trunk/boost/intrusive/detail/ebo_functor_holder.hpp (original)
+++ trunk/boost/intrusive/detail/ebo_functor_holder.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -26,18 +26,18 @@
ebo_functor_holder_impl()
{}
ebo_functor_holder_impl(const T& t)
- : t(t)
+ : t_(t)
{}
template<class Arg1, class Arg2>
ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
- : t(arg1, arg2)
+ : t_(arg1, arg2)
{}
- T& get(){return t;}
- const T& get()const{return t;}
+ T& get(){return t_;}
+ const T& get()const{return t_;}
private:
- T t;
+ T t_;
};
template<typename T>
Modified: trunk/boost/intrusive/detail/parent_from_member.hpp
==============================================================================
--- trunk/boost/intrusive/detail/parent_from_member.hpp (original)
+++ trunk/boost/intrusive/detail/parent_from_member.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -15,7 +15,8 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <cstddef>
-#if defined(BOOST_MSVC) || (defined (BOOST_WINDOWS) && defined(BOOST_INTEL))
+#if defined(BOOST_MSVC) || ((defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && defined(BOOST_INTEL))
+
#define BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER
#include <boost/cstdint.hpp>
#endif
Modified: trunk/boost/intrusive/detail/tree_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/tree_node.hpp (original)
+++ trunk/boost/intrusive/detail/tree_node.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -99,8 +99,8 @@
: members_ (0, 0)
{}
- explicit tree_iterator(node_ptr node, const Container *cont_ptr)
- : members_ (node, cont_ptr)
+ explicit tree_iterator(node_ptr nodeptr, const Container *cont_ptr)
+ : members_ (nodeptr, cont_ptr)
{}
tree_iterator(tree_iterator<Container, false> const& other)
@@ -110,8 +110,8 @@
const node_ptr &pointed_node() const
{ return members_.nodeptr_; }
- tree_iterator &operator=(const node_ptr &node)
- { members_.nodeptr_ = node; return static_cast<tree_iterator&>(*this); }
+ tree_iterator &operator=(const node_ptr &nodeptr)
+ { members_.nodeptr_ = nodeptr; return static_cast<tree_iterator&>(*this); }
public:
tree_iterator& operator++()
Modified: trunk/boost/intrusive/hashtable.hpp
==============================================================================
--- trunk/boost/intrusive/hashtable.hpp (original)
+++ trunk/boost/intrusive/hashtable.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -718,6 +718,8 @@
//Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
+ //Cache begin is incompatible with auto-unlink hooks!
+ BOOST_STATIC_ASSERT(!(cache_begin && ((int)real_value_traits::link_mode == (int)auto_unlink)));
template<class Disposer>
node_cast_adaptor<detail::node_disposer<Disposer, hashtable_impl> >
@@ -871,7 +873,7 @@
//! <b>Effects</b>: Returns true if the container is empty.
//!
- //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
+ //! <b>Complexity</b>: if constant-time size and cache_begin options are disabled,
//! average constant time (worst case, with empty() == true: O(this->bucket_count()).
//! Otherwise constant.
//!
Modified: trunk/boost/intrusive/list.hpp
==============================================================================
--- trunk/boost/intrusive/list.hpp (original)
+++ trunk/boost/intrusive/list.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -978,7 +978,8 @@
carry.splice(carry.cbegin(), *this, this->cbegin());
int i = 0;
while(i < fill && !counter[i].empty()) {
- carry.merge(counter[i++], p);
+ counter[i].merge(carry, p);
+ carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if(i == fill)
@@ -1021,21 +1022,26 @@
template<class Predicate>
void merge(list_impl& x, Predicate p)
{
- const_iterator e(this->end());
- const_iterator bx(x.begin());
- const_iterator ex(x.end());
-
- for (const_iterator b = this->cbegin(); b != e; ++b) {
- size_type n(0);
- const_iterator ix(bx);
- while(ix != ex && p(*ix, *b)){
- ++ix; ++n;
+ const_iterator e(this->cend()), ex(x.cend());
+ const_iterator b(this->cbegin());
+ while(!x.empty()){
+ const_iterator ix(x.cbegin());
+ while (b != e && !p(*ix, *b)){
+ ++b;
+ }
+ if(b == e){
+ //Now transfer the rest to the end of the container
+ this->splice(e, x);
+ break;
+ }
+ else{
+ size_type n(0);
+ do{
+ ++ix; ++n;
+ } while(ix != ex && p(*ix, *b));
+ this->splice(b, x, x.begin(), ix, n);
}
- this->splice(b, x, bx, ix, n);
- bx = ix;
}
- //Now transfer the rest at the end of the container
- this->splice(e, x);
}
//! <b>Effects</b>: Reverses the order of elements in the list.
Modified: trunk/boost/intrusive/rbtree.hpp
==============================================================================
--- trunk/boost/intrusive/rbtree.hpp (original)
+++ trunk/boost/intrusive/rbtree.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -513,9 +513,9 @@
template<class Iterator>
void insert_equal(Iterator b, Iterator e)
{
- iterator end(this->end());
+ iterator iend(this->end());
for (; b != e; ++b)
- this->insert_equal(end, *b);
+ this->insert_equal(iend, *b);
}
//! <b>Requires</b>: value must be an lvalue
@@ -579,9 +579,9 @@
void insert_unique(Iterator b, Iterator e)
{
if(this->empty()){
- iterator end(this->end());
+ iterator iend(this->end());
for (; b != e; ++b)
- this->insert_unique(end, *b);
+ this->insert_unique(iend, *b);
}
else{
for (; b != e; ++b)
Modified: trunk/boost/intrusive/slist.hpp
==============================================================================
--- trunk/boost/intrusive/slist.hpp (original)
+++ trunk/boost/intrusive/slist.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -598,7 +598,7 @@
void swap(slist_impl& other)
{
if(cache_last){
- this->priv_swap_cache_last(other);
+ priv_swap_cache_last(this, &other);
}
else{
this->priv_swap_lists(this->get_root_node(), other.get_root_node(), detail::bool_<linear>());
@@ -1264,6 +1264,7 @@
carry.splice_after(carry.cbefore_begin(), *this, this->cbefore_begin());
int i = 0;
while(i < fill && !counter[i].empty()) {
+ carry.swap(counter[i]);
last_inserted = carry.merge(counter[i++], p);
}
BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
@@ -1340,24 +1341,26 @@
template<class Predicate>
iterator merge(slist_impl& x, Predicate p)
{
- const_iterator a(cbefore_begin()), e(cend()), ax(x.cbefore_begin()), ex(x.cend());
- const_iterator last_inserted(e);
- const_iterator a_next;
- while(++(a_next = a) != e && !x.empty()) {
- const_iterator ix(ax);
- const_iterator cx;
- size_type n(0);
- while(++(cx = ix) != ex && p(*cx, *a_next)){
- ++ix; ++n;
+ const_iterator e(this->cend()), ex(x.cend()), bb(this->cbefore_begin()),
+ bb_next, last_inserted(e);
+ while(!x.empty()){
+ const_iterator ibx_next(x.cbefore_begin()), ibx(ibx_next++);
+ while (++(bb_next = bb) != e && !p(*ibx_next, *bb_next)){
+ bb = bb_next;
}
- if(ax != ix){
- this->splice_after(a, x, ax, ix, n);
- last_inserted = ix;
+ if(bb_next == e){
+ //Now transfer the rest to the end of the container
+ last_inserted = this->splice_after(bb, x);
+ break;
+ }
+ else{
+ size_type n(0);
+ do{
+ ibx = ibx_next; ++n;
+ } while(++(ibx_next = ibx) != ex && p(*ibx_next, *bb_next));
+ this->splice_after(bb, x, x.before_begin(), ibx, n);
+ last_inserted = ibx;
}
- a = a_next;
- }
- if (!x.empty()){
- last_inserted = this->splice_after(a, x);
}
return last_inserted.unconst();
}
@@ -1711,22 +1714,40 @@
}
}
- void priv_swap_cache_last(slist_impl &other)
+ static void priv_swap_cache_last(slist_impl *this_impl, slist_impl *other_impl)
{
- node_ptr other_last(other.get_last_node());
- node_ptr this_last(this->get_last_node());
- node_ptr other_bfirst(other.get_root_node());
- node_ptr this_bfirst(this->get_root_node());
- node_algorithms::transfer_after(this_bfirst, other_bfirst, other_last);
- node_algorithms::transfer_after(other_bfirst, other_last != other_bfirst? other_last : this_bfirst, this_last);
- node_ptr tmp(this->get_last_node());
- this->set_last_node(other.get_last_node());
- other.set_last_node(tmp);
- if(this->get_last_node() == other_bfirst){
- this->set_last_node(this_bfirst);
+ bool other_was_empty = false;
+ if(this_impl->empty()){
+ //Check if both are empty or
+ if(other_impl->empty())
+ return;
+ //If this is empty swap pointers
+ slist_impl *tmp = this_impl;
+ this_impl = other_impl;
+ other_impl = tmp;
+ other_was_empty = true;
+ }
+ else{
+ other_was_empty = other_impl->empty();
}
- if(other.get_last_node() == this_bfirst){
- other.set_last_node(other_bfirst);
+
+ //Precondition: this is not empty
+ node_ptr other_old_last(other_impl->get_last_node());
+ node_ptr other_bfirst(other_impl->get_root_node());
+ node_ptr this_bfirst(this_impl->get_root_node());
+ node_ptr this_old_last(this_impl->get_last_node());
+
+ //Move all nodes from this to other's beginning
+ node_algorithms::transfer_after(other_bfirst, this_bfirst, this_old_last);
+ other_impl->set_last_node(this_old_last);
+
+ if(other_was_empty){
+ this_impl->set_last_node(this_bfirst);
+ }
+ else{
+ //Move trailing nodes from other to this
+ node_algorithms::transfer_after(this_bfirst, this_old_last, other_old_last);
+ this_impl->set_last_node(other_old_last);
}
}
Modified: trunk/libs/interprocess/doc/Jamfile.v2
==============================================================================
--- trunk/libs/interprocess/doc/Jamfile.v2 (original)
+++ trunk/libs/interprocess/doc/Jamfile.v2 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -25,8 +25,15 @@
<doxygen:param>EXTRACT_ALL=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>EXTRACT_PRIVATE=NO
+ <doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
- <doxygen:param>PREDEFINED=BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ <doxygen:param>MACRO_EXPANSION=YES
+ <doxygen:param>"PREDEFINED=\"BOOST_INTERPROCESS_DOXYGEN_INVOKED\" \\
+ \"BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(a)= \" \\
+ \"BOOST_INTERPROCESS_RV_REF(a)=a &&\" \\
+ \"BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(a)=a &&\" \\
+ \"BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(a)=a &&\" \\
+ \"BOOST_INTERPROCESS_FWD_REF(a)=a &&\""
<xsl:param>"boost.doxygen.reftitle=Boost.Interprocess Reference"
;
Modified: trunk/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- trunk/libs/interprocess/doc/interprocess.qbk (original)
+++ trunk/libs/interprocess/doc/interprocess.qbk 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -94,13 +94,8 @@
message to that buffer, send the offset of that portion of shared
memory to another process, and you are done. Let's see the example:
-[import ../example/doc_ipc_messageA.cpp]
-[doc_ipc_messageA]
-
-In receiver process one just could write the following lines:
-
-[import ../example/doc_ipc_messageB.cpp]
-[doc_ipc_messageB]
+[import ../example/doc_ipc_message.cpp]
+[doc_ipc_message]
[endsect]
@@ -108,15 +103,10 @@
You want to create objects in a shared memory segment, giving a string name to them so that
any other process can find, use and delete them from the segment when the objects are not
-needed anymore. Just write in one process:
-
-[import ../example/doc_named_allocA.cpp]
-[doc_named_allocA]
+needed anymore. Example:
-In other process execute the following:
-
-[import ../example/doc_named_allocB.cpp]
-[doc_named_allocB]
+[import ../example/doc_named_alloc.cpp]
+[doc_named_alloc]
[endsect]
@@ -148,16 +138,19 @@
mapped files. For example, we can construct STL-like containers in shared memory.
To do this, we just need to create a special (managed) shared memory segment,
declare a [*Boost.Interprocess] allocator and construct the vector in shared memory
-just if it was any other object. Just execute this first process:
-
-[import ../example/doc_contA.cpp]
-[doc_contA]
+just if it was any other object.
-After this process is executed we can search the constructed vector and use it with
-STL algorithms:
-
-[import ../example/doc_contB.cpp]
-[doc_contB]
+The class that allows this complex structures in shared memory is called
+[classref boost::interprocess::managed_shared_memory] and it's easy to use.
+Just execute this example without arguments:
+
+[import ../example/doc_spawn_vector.cpp]
+[doc_spawn_vector]
+
+The parent process will create an special shared memory class that allows easy construction
+of many complex data structures associated with a name. The parent process executes the same
+program with an additional argument so the child process opens the shared memory and uses
+the vector and erases it.
[endsect]
@@ -498,16 +491,11 @@
Let's see a simple example of shared memory use. A server process creates a
shared memory object, maps it and initializes all the bytes to a value. After that,
a client process opens the shared memory, maps it, and checks
-that the data is correctly initialized. This is the server process:
+that the data is correctly initialized:
[import ../example/doc_shared_memory.cpp]
[doc_shared_memory]
-Now the client process:
-
-[import ../example/doc_shared_memory2.cpp]
-[doc_shared_memory2]
-
[endsect]
[section:emulation Emulation for systems without shared memory objects]
@@ -521,12 +509,11 @@
defined by POSIX (see [link interprocess.sharedmemorybetweenprocesses.sharedmemory.windows_shared_memory
Native windows shared memory] section for more information).
-* Some UNIX systems don't support shared memory objects at all. MacOS is
- one of these operating systems.
+* Some UNIX systems don't fully support POSIX shared memory objects at all.
In those platforms, shared memory is emulated with mapped files created
in the temporary files directory. Because of this emulation, shared memory
-has filesystem lifetime in those systems.
+has filesystem lifetime in some of those systems.
[endsect]
@@ -554,12 +541,9 @@
shared memory object of this name exists (that is, trying to open an object
with that name will fail and an object of the same name can be created again).
-In Windows operating systems, the function fails if the object is being used,
-so a programmer can't consider the UNIX behavior as the portable behavior:
-
-`shared_memory_object::remove` [*can] fail if the shared memory is still in use,
-but this does not mean that it [*will] fail if it's in use. Just the same
-behavior as the standard C (stdio.h) `int remove(const char *path)` function.
+In Windows operating systems, current version supports an usually acceptable emulation
+of the UNIX unlink behaviour: the file is randomly renamed and marked as to be deleted when
+the last open handle is closed.
[endsect]
@@ -586,7 +570,6 @@
[endsect]
-
[section:windows_shared_memory Native windows shared memory]
Windows operating system also offers shared memory, but the lifetime of this
@@ -624,20 +607,13 @@
a client process opens the shared memory, maps it, and checks
that the data is correctly initialized. Take in care that [*if the server exits before
the client connects to the shared memory the client connection will fail], because
-the shared memory segment is destroyed when no processes are attached to the memory.
+the shared memory segment is destroyed when no proces is attached to the memory.
This is the server process:
[import ../example/doc_windows_shared_memory.cpp]
[doc_windows_shared_memory]
-Now, before destroying the
-[classref boost::interprocess::windows_shared_memory windows_shared memory]
-object, launch the client process:
-
-[import ../example/doc_windows_shared_memory2.cpp]
-[doc_windows_shared_memory2]
-
As we can see, native windows shared memory needs synchronization to make sure
that the shared memory won't be destroyed before the client is launched.
@@ -801,16 +777,11 @@
memory mapped files. A server process creates a shared
memory segment, maps it and initializes all the bytes to a value. After that,
a client process opens the shared memory, maps it, and checks
-that the data is correctly initialized. This is the server process:
+that the data is correctly initialized::
[import ../example/doc_file_mapping.cpp]
[doc_file_mapping]
-Now the client process:
-
-[import ../example/doc_file_mapping2.cpp]
-[doc_file_mapping2]
-
[endsect]
[endsect]
@@ -1478,17 +1449,17 @@
This is the process main process. Creates the shared memory, constructs
the cyclic buffer and start writing traces:
-[import ../example/doc_anonymous_mutexA.cpp]
+[import ../example/comp_doc_anonymous_mutexA.cpp]
[doc_anonymous_mutexA]
The second process opens the shared memory, obtains access to the cyclic buffer
and starts writing traces:
-[import ../example/doc_anonymous_mutexB.cpp]
+[import ../example/comp_doc_anonymous_mutexB.cpp]
[doc_anonymous_mutexB]
-As we can see, a mutex is useful to protect data but not to notify to another process
-an event. For this, we need a condition variable, as we will see in the next section.
+As we can see, a mutex is useful to protect data but not to notify an event to another
+process. For this, we need a condition variable, as we will see in the next section.
[endsect]
@@ -1583,13 +1554,13 @@
the buffer and starts writing messages one by one until it writes "last message"
to indicate that there are no more messages to print:
-[import ../example/doc_anonymous_conditionA.cpp]
+[import ../example/comp_doc_anonymous_conditionA.cpp]
[doc_anonymous_conditionA]
The second process opens the shared memory and prints each message
until the "last message" message is received:
-[import ../example/doc_anonymous_conditionB.cpp]
+[import ../example/comp_doc_anonymous_conditionB.cpp]
[doc_anonymous_conditionB]
With condition variables, a process can block if it can't continue the work,
@@ -1665,13 +1636,13 @@
the integer array and starts integers one by one, blocking if the array
is full:
-[import ../example/doc_anonymous_semaphoreA.cpp]
+[import ../example/comp_doc_anonymous_semaphoreA.cpp]
[doc_anonymous_semaphoreA]
The second process opens the shared memory and copies the received integers
to it's own buffer:
-[import ../example/doc_anonymous_semaphoreB.cpp]
+[import ../example/comp_doc_anonymous_semaphoreB.cpp]
[doc_anonymous_semaphoreB]
The same interprocess communication can be achieved with a condition variables
@@ -2152,11 +2123,11 @@
[/section:upgradable_mutexes_example Anonymous Upgradable Mutex Example]
-[/import ../example/doc_anonymous_upgradable_mutexA.cpp]
+[/import ../example/comp_doc_anonymous_upgradable_mutexA.cpp]
[/doc_anonymous_upgradable_mutexA]
-[/import ../example/doc_anonymous_upgradable_mutexB.cpp]
+[/import ../example/comp_doc_anonymous_upgradable_mutexB.cpp]
[/doc_anonymous_upgradable_mutexB]
[/endsect]
@@ -2722,7 +2693,7 @@
POSIX, when two file descriptors are used to lock a file if a descriptor is closed,
all file locks set by the calling process are cleared.
-To sum up, if you plan to use file locking in your processes, use the following
+To sum up, if you plan to use portable file locking in your processes, use the following
restrictions:
* [*For each file, use a single `file_lock` object per process.]
@@ -2867,12 +2838,12 @@
an array of integers on it. The other process just reads the array and checks that
the sequence number is correct. This is the first process:
-[import ../example/doc_message_queueA.cpp]
+[import ../example/comp_doc_message_queueA.cpp]
[doc_message_queueA]
This is the second process:
-[import ../example/doc_message_queueB.cpp]
+[import ../example/comp_doc_message_queueB.cpp]
[doc_message_queueB]
To know more about this class and all its operations, please see the
@@ -3246,11 +3217,16 @@
managed_mapped_file mfile (open_or_create, "MyMappedFile", //Mapped file name 65536); //Mapped file size
When the `managed_mapped_file` object is destroyed, the file is
automatically unmapped, and all the resources are freed. To remove
-the file from the filesystem you can use standard C `std::remove`
-or [*Boost.Filesystem]'s `remove()` functions. File removing might fail
+the file from the filesystem you could use standard C `std::remove`
+or [*Boost.Filesystem]'s `remove()` functions, but file removing might fail
if any process still has the file mapped in memory or the file is open
by any process.
+To obtain a more portable behaviour, use `file_mapping::remove(const char *)` operation, which
+will remove the file even if it's being mapped. However, removal will fail in some OS systems if
+the file (eg. by C++ file streams) and no delete share permission was granted to the file. But in
+most common cases `file_mapping::remove` is portable enough.
+
[endsect]
For more information about managed mapped file capabilities, see
@@ -3871,20 +3847,20 @@
[c++]
- enum allocation_type
+ enum boost::interprocess::allocation_type
{
//Bitwise OR (|) combinable values
- allocate_new = ...,
- expand_fwd = ...,
- expand_bwd = ...,
- shrink_in_place = ...,
- nothrow_allocation = ...
+ boost::interprocess::allocate_new = ...,
+ boost::interprocess::expand_fwd = ...,
+ boost::interprocess::expand_bwd = ...,
+ boost::interprocess::shrink_in_place = ...,
+ boost::interprocess::nothrow_allocation = ...
};
template<class T>
std::pair<T *, bool>
- allocation_command( allocation_type command
+ allocation_command( boost::interprocess::allocation_type command
, std::size_t limit_size
, std::size_t preferred_size
, std::size_t &received_size
@@ -3893,66 +3869,66 @@
[*Preconditions for the function]:
-* If the parameter command contains the value `shrink_in_place` it can't
-contain any of these values: `expand_fwd`, `expand_bwd`.
+* If the parameter command contains the value `boost::interprocess::shrink_in_place` it can't
+contain any of these values: `boost::interprocess::expand_fwd`, `boost::interprocess::expand_bwd`.
-* If the parameter command contains `expand_fwd` or `expand_bwd`, the parameter
+* If the parameter command contains `boost::interprocess::expand_fwd` or `boost::interprocess::expand_bwd`, the parameter
`reuse_ptr` must be non-null and returned by a previous allocation function.
-* If the parameter command contains the value `shrink_in_place`, the parameter
+* If the parameter command contains the value `boost::interprocess::shrink_in_place`, the parameter
`limit_size` must be equal or greater than the parameter `preferred_size`.
-* If the parameter `command` contains any of these values: `expand_fwd` or `expand_bwd`,
+* If the parameter `command` contains any of these values: `boost::interprocess::expand_fwd` or `boost::interprocess::expand_bwd`,
the parameter `limit_size` must be equal or less than the parameter `preferred_size`.
[*Which are the effects of this function:]
-* If the parameter command contains the value `shrink_in_place`, the function
+* If the parameter command contains the value `boost::interprocess::shrink_in_place`, the function
will try to reduce the size of the memory block referenced by pointer `reuse_ptr`
to the value `preferred_size` moving only the end of the block.
If it's not possible, it will try to reduce the size of the memory block as
much as possible as long as this results in `size(p) <= limit_size`. Success
is reported only if this results in `preferred_size <= size(p)` and `size(p) <= limit_size`.
-* If the parameter `command` only contains the value `expand_fwd` (with optional
- additional `nothrow_allocation`), the allocator will try to increase the size of the
+* If the parameter `command` only contains the value `boost::interprocess::expand_fwd` (with optional
+ additional `boost::interprocess::nothrow_allocation`), the allocator will try to increase the size of the
memory block referenced by pointer reuse moving only the end of the block to the
value `preferred_size`. If it's not possible, it will try to increase the size
of the memory block as much as possible as long as this results in
`size(p) >= limit_size`. Success is reported only if this results in `limit_size <= size(p)`.
-* If the parameter `command` only contains the value `expand_bwd` (with optional
- additional `nothrow_allocation`), the allocator will try to increase the size of
+* If the parameter `command` only contains the value `boost::interprocess::expand_bwd` (with optional
+ additional `boost::interprocess::nothrow_allocation`), the allocator will try to increase the size of
the memory block referenced by pointer `reuse_ptr` only moving the start of the
block to a returned new position `new_ptr`. If it's not possible, it will try to
move the start of the block as much as possible as long as this results in
`size(new_ptr) >= limit_size`. Success is reported only if this results in
`limit_size <= size(new_ptr)`.
-* If the parameter `command` only contains the value `allocate_new` (with optional
- additional `nothrow_allocation`), the allocator will try to allocate memory for
+* If the parameter `command` only contains the value `boost::interprocess::allocate_new` (with optional
+ additional `boost::interprocess::nothrow_allocation`), the allocator will try to allocate memory for
`preferred_size` objects. If it's not possible it will try to allocate memory for
at least `limit_size` objects.
-* If the parameter `command` only contains a combination of `expand_fwd` and
- `allocate_new`, (with optional additional `nothrow_allocation`) the allocator will
+* If the parameter `command` only contains a combination of `boost::interprocess::expand_fwd` and
+ `boost::interprocess::allocate_new`, (with optional additional `boost::interprocess::nothrow_allocation`) the allocator will
try first the forward expansion. If this fails, it would try a new allocation.
-* If the parameter `command` only contains a combination of `expand_bwd` and
- `allocate_new` (with optional additional `nothrow_allocation`), the allocator will
+* If the parameter `command` only contains a combination of `boost::interprocess::expand_bwd` and
+ `boost::interprocess::allocate_new` (with optional additional `boost::interprocess::nothrow_allocation`), the allocator will
try first to obtain `preferred_size` objects using both methods if necessary.
If this fails, it will try to obtain `limit_size` objects using both methods if
necessary.
-* If the parameter `command` only contains a combination of `expand_fwd` and
- `expand_bwd` (with optional additional `nothrow_allocation`), the allocator will
+* If the parameter `command` only contains a combination of `boost::interprocess::expand_fwd` and
+ `boost::interprocess::expand_bwd` (with optional additional `boost::interprocess::nothrow_allocation`), the allocator will
try first forward expansion. If this fails it will try to obtain preferred_size
objects using backwards expansion or a combination of forward and backwards expansion.
If this fails, it will try to obtain `limit_size` objects using both methods if
necessary.
* If the parameter `command` only contains a combination of allocation_new,
- `expand_fwd` and `expand_bwd`, (with optional additional `nothrow_allocation`)
+ `boost::interprocess::expand_fwd` and `boost::interprocess::expand_bwd`, (with optional additional `boost::interprocess::nothrow_allocation`)
the allocator will try first forward expansion. If this fails it will try to obtain
preferred_size objects using new allocation, backwards expansion or a combination of
forward and backwards expansion. If this fails, it will try to obtain `limit_size`
@@ -3967,13 +3943,13 @@
* The allocator is unable to allocate/expand/shrink the memory or there is an
error in preconditions
-* The parameter command does not contain `nothrow_allocation`.
+* The parameter command does not contain `boost::interprocess::nothrow_allocation`.
[*This function returns:]
* The address of the allocated memory or the new address of the expanded memory
as the first member of the pair. If the parameter command contains
- `nothrow_allocation` the first member will be 0
+ `boost::interprocess::nothrow_allocation` the first member will be 0
if the allocation/expansion fails or there is an error in preconditions.
* The second member of the pair will be false if the memory has been allocated,
@@ -5018,7 +4994,7 @@
[endsect]
-[section:containers_and_move_semantics Move semantics in Interprocess containers]
+[section:containers_and_move Move semantics in Interprocess containers]
[*Boost.Interprocess] containers support move semantics, which means that the contents
of a container can be moved from a container two another one, without any copying. The
@@ -5030,7 +5006,7 @@
To transfer the contents of a container to another one, use
-`boost::interprocess::move()` function, as shown in the example. For more details
+`boost::move()` function, as shown in the example. For more details
about functions supporting move-semantics, see the reference section of
Boost.Interprocess containers:
@@ -6541,6 +6517,17 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_39_00 Boost 1.39 Release]
+
+* Added experimental `stable_vector` container.
+* `shared_memory_object::remove` has now POSIX `unlink` semantics and
+ `file_mapping::remove` was added to obtain POSIX `unlink` semantics with mapped files.
+* Shared memory in windows has now kernel lifetime instead of filesystem lifetime: shared
+ memory will disappear when the system reboots.
+* Updated move semantics.
+
+[endsect]
+
[section:release_notes_boost_1_38_00 Boost 1.38 Release]
* Updated documentation to show rvalue-references funcions instead of emulation functions.
Modified: trunk/libs/interprocess/example/Jamfile.v2
==============================================================================
--- trunk/libs/interprocess/example/Jamfile.v2 (original)
+++ trunk/libs/interprocess/example/Jamfile.v2 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,7 +19,7 @@
{
local all_rules = ;
- for local fileb in [ glob *.cpp ]
+ for local fileb in [ glob comp*.cpp ]
{
all_rules += [ link $(fileb) /boost/thread//boost_thread
: # additional args
@@ -28,6 +28,17 @@
] ;
}
+ for local fileb in [ glob doc_*.cpp ]
+ {
+ all_rules += [ run $(fileb) /boost/thread//boost_thread
+ : # additional args
+ : # test-files
+ : # requirements
+ <toolset>acc:<linkflags>-lrt
+ <toolset>acc-pa_risc:<linkflags>-lrt
+ ] ;
+ }
+
return $(all_rules) ;
}
Added: trunk/libs/interprocess/example/comp_doc_anonymous_conditionA.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_conditionA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_conditionA
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <iostream>
+#include <cstdio>
+#include "doc_anonymous_condition_shared_data.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+
+ //Erase previous shared memory and schedule erasure on exit
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a shared memory object.
+ shared_memory_object shm
+ (create_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+ try{
+ //Set size
+ shm.truncate(sizeof(trace_queue));
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Construct the shared structure in memory
+ trace_queue * data = new (addr) trace_queue;
+
+ const int NumMsg = 100;
+
+ for(int i = 0; i < NumMsg; ++i){
+ scoped_lock<interprocess_mutex> lock(data->mutex);
+ if(data->message_in){
+ data->cond_full.wait(lock);
+ }
+ if(i == (NumMsg-1))
+ std::sprintf(data->items, "%s", "last message");
+ else
+ std::sprintf(data->items, "%s_%d", "my_trace", i);
+
+ //Notify to the other process that there is a message
+ data->cond_empty.notify_one();
+
+ //Mark message buffer as full
+ data->message_in = true;
+ }
+ }
+ catch(interprocess_exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_conditionB.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_conditionB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,71 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_conditionB
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <iostream>
+#include <cstring>
+#include "doc_anonymous_condition_shared_data.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ //Create a shared memory object.
+ shared_memory_object shm
+ (open_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ try{
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Obtain a pointer to the shared structure
+ trace_queue * data = static_cast<trace_queue*>(addr);
+
+ //Print messages until the other process marks the end
+ bool end_loop = false;
+ do{
+ scoped_lock<interprocess_mutex> lock(data->mutex);
+ if(!data->message_in){
+ data->cond_empty.wait(lock);
+ }
+ if(std::strcmp(data->items, "last message") == 0){
+ end_loop = true;
+ }
+ else{
+ //Print the message
+ std::cout << data->items << std::endl;
+ //Notify the other process that the buffer is empty
+ data->message_in = false;
+ data->cond_full.notify_one();
+ }
+ }
+ while(!end_loop);
+ }
+ catch(interprocess_exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_mutexA.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_mutexA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,78 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_mutexA
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include "doc_anonymous_mutex_shared_data.hpp"
+#include <iostream>
+#include <cstdio>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a shared memory object.
+ shared_memory_object shm
+ (create_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ //Set size
+ shm.truncate(sizeof(shared_memory_log));
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Construct the shared structure in memory
+ shared_memory_log * data = new (addr) shared_memory_log;
+
+ //Write some logs
+ for(int i = 0; i < shared_memory_log::NumItems; ++i){
+ //Lock the mutex
+ scoped_lock<interprocess_mutex> lock(data->mutex);
+ std::sprintf(data->items[(data->current_line++) % shared_memory_log::NumItems]
+ ,"%s_%d", "process_a", i);
+ if(i == (shared_memory_log::NumItems-1))
+ data->end_a = true;
+ //Mutex is released here
+ }
+
+ //Wait until the other process ends
+ while(1){
+ scoped_lock<interprocess_mutex> lock(data->mutex);
+ if(data->end_b)
+ break;
+ }
+ }
+ catch(interprocess_exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_mutexB.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_mutexB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,68 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_mutexB
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include "doc_anonymous_mutex_shared_data.hpp"
+#include <iostream>
+#include <cstdio>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ //Remove shared memory on destruction
+ struct shm_destroy
+ {
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Open the shared memory object.
+ shared_memory_object shm
+ (open_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Construct the shared structure in memory
+ shared_memory_log * data = static_cast<shared_memory_log*>(addr);
+
+ //Write some logs
+ for(int i = 0; i < 100; ++i){
+ //Lock the mutex
+ scoped_lock<interprocess_mutex> lock(data->mutex);
+ std::sprintf(data->items[(data->current_line++) % shared_memory_log::NumItems]
+ ,"%s_%d", "process_a", i);
+ if(i == (shared_memory_log::NumItems-1))
+ data->end_b = true;
+ //Mutex is released here
+ }
+
+ //Wait until the other process ends
+ while(1){
+ scoped_lock<interprocess_mutex> lock(data->mutex);
+ if(data->end_a)
+ break;
+ }
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_semaphoreA.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_semaphoreA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,64 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_semaphoreA
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <iostream>
+#include "doc_anonymous_semaphore_shared_data.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a shared memory object.
+ shared_memory_object shm
+ (create_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ //Set size
+ shm.truncate(sizeof(shared_memory_buffer));
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Construct the shared structure in memory
+ shared_memory_buffer * data = new (addr) shared_memory_buffer;
+
+ const int NumMsg = 100;
+
+ //Insert data in the array
+ for(int i = 0; i < NumMsg; ++i){
+ data->nempty.wait();
+ data->mutex.wait();
+ data->items[i % shared_memory_buffer::NumItems] = i;
+ data->mutex.post();
+ data->nstored.post();
+ }
+
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_semaphoreB.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_semaphoreB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,61 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_semaphoreB
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <iostream>
+#include "doc_anonymous_semaphore_shared_data.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ //Remove shared memory on destruction
+ struct shm_destroy
+ {
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a shared memory object.
+ shared_memory_object shm
+ (open_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Obtain the shared structure
+ shared_memory_buffer * data = static_cast<shared_memory_buffer*>(addr);
+
+ const int NumMsg = 100;
+
+ int extracted_data [NumMsg];
+
+ //Extract the data
+ for(int i = 0; i < NumMsg; ++i){
+ data->nstored.wait();
+ data->mutex.wait();
+ extracted_data[i] = data->items[i % shared_memory_buffer::NumItems];
+ data->mutex.post();
+ data->nempty.post();
+ }
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexA.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,72 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_anonymous_upgradable_mutexA
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include "doc_upgradable_mutex_shared_data.hpp"
+#include <iostream>
+#include <cstdio>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ //Remove shared memory on destruction
+ struct shm_destroy
+ {
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a shared memory object.
+ shared_memory_object shm
+ (create_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ //Set size
+ shm.truncate(sizeof(shared_data));
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Construct the shared structure in memory
+ shared_data * data = new (addr) shared_data;
+
+ //Write some logs
+ for(int i = 0; i < shared_data::NumItems; ++i){
+ //Lock the upgradable_mutex
+ scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
+ std::sprintf(data->items[(data->current_line++) % shared_data::NumItems]
+ ,"%s_%d", "process_a", i);
+ if(i == (shared_data::NumItems-1))
+ data->end_a = true;
+ //Mutex is released here
+ }
+
+ //Wait until the other process ends
+ while(1){
+ scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
+ if(data->end_b)
+ break;
+ }
+
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexB.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_anonymous_upgradable_mutexB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,70 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+
+//[doc_anonymous_upgradable_mutexB
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include "doc_upgradable_mutex_shared_data.hpp"
+#include <iostream>
+#include <cstdio>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ //Remove shared memory on destruction
+ struct shm_destroy
+ {
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Open the shared memory object.
+ shared_memory_object shm
+ (open_only //only create
+ ,"MySharedMemory" //name
+ ,read_write //read-write mode
+ );
+
+ //Map the whole shared memory in this process
+ mapped_region region
+ (shm //What to map
+ ,read_write //Map it as read-write
+ );
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+
+ //Construct the shared structure in memory
+ shared_data * data = static_cast<shared_data*>(addr);
+
+ //Write some logs
+ for(int i = 0; i < 100; ++i){
+ //Lock the upgradable_mutex
+ scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
+ std::sprintf(data->items[(data->current_line++) % shared_data::NumItems]
+ ,"%s_%d", "process_a", i);
+ if(i == (shared_data::NumItems-1))
+ data->end_b = true;
+ //Mutex is released here
+ }
+
+ //Wait until the other process ends
+ while(1){
+ scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
+ if(data->end_a)
+ break;
+ }
+ return 0;
+}
+//]
+
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_message_queueA.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_message_queueA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_message_queueA
+#include <boost/interprocess/ipc/message_queue.hpp>
+#include <iostream>
+#include <vector>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ //Erase previous message queue
+ message_queue::remove("message_queue");
+
+ //Create a message_queue.
+ message_queue mq
+ (create_only //only create
+ ,"message_queue" //name
+ ,100 //max message number
+ ,sizeof(int) //max message size
+ );
+
+ //Send 100 numbers
+ for(int i = 0; i < 100; ++i){
+ mq.send(&i, sizeof(i), 0);
+ }
+ }
+ catch(interprocess_exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Added: trunk/libs/interprocess/example/comp_doc_message_queueB.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/comp_doc_message_queueB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,47 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+//[doc_message_queueB
+#include <boost/interprocess/ipc/message_queue.hpp>
+#include <iostream>
+#include <vector>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ //Open a message queue.
+ message_queue mq
+ (open_only //only create
+ ,"message_queue" //name
+ );
+
+ unsigned int priority;
+ std::size_t recvd_size;
+
+ //Receive 100 numbers
+ for(int i = 0; i < 100; ++i){
+ int number;
+ mq.receive(&number, sizeof(number), recvd_size, priority);
+ if(number != i || recvd_size != sizeof(number))
+ return 1;
+ }
+ }
+ catch(interprocess_exception &ex){
+ message_queue::remove("message_queue");
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ message_queue::remove("message_queue");
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_adaptive_pool.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_adaptive_pool.cpp (original)
+++ trunk/libs/interprocess/example/doc_adaptive_pool.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,46 +18,44 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Create a adaptive_pool that allocates ints from the managed segment
+ //The number of chunks per segment is the default value
+ typedef adaptive_pool<int, managed_shared_memory::segment_manager>
+ adaptive_pool_t;
+ adaptive_pool_t allocator_instance(segment.get_segment_manager());
+
+ //Create another adaptive_pool. Since the segment manager address
+ //is the same, this adaptive_pool will be
+ //attached to the same pool so "allocator_instance2" can deallocate
+ //nodes allocated by "allocator_instance"
+ adaptive_pool_t allocator_instance2(segment.get_segment_manager());
+
+ //Create another adaptive_pool using copy-constructor. This
+ //adaptive_pool will also be attached to the same pool
+ adaptive_pool_t allocator_instance3(allocator_instance2);
+
+ //All allocators are equal
+ assert(allocator_instance == allocator_instance2);
+ assert(allocator_instance2 == allocator_instance3);
+
+ //So memory allocated with one can be deallocated with another
+ allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
+ allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Create a adaptive_pool that allocates ints from the managed segment
- //The number of chunks per segment is the default value
- typedef adaptive_pool<int, managed_shared_memory::segment_manager>
- adaptive_pool_t;
- adaptive_pool_t allocator_instance(segment.get_segment_manager());
-
- //Create another adaptive_pool. Since the segment manager address
- //is the same, this adaptive_pool will be
- //attached to the same pool so "allocator_instance2" can deallocate
- //nodes allocated by "allocator_instance"
- adaptive_pool_t allocator_instance2(segment.get_segment_manager());
-
- //Create another adaptive_pool using copy-constructor. This
- //adaptive_pool will also be attached to the same pool
- adaptive_pool_t allocator_instance3(allocator_instance2);
-
- //All allocators are equal
- assert(allocator_instance == allocator_instance2);
- assert(allocator_instance2 == allocator_instance3);
-
- //So memory allocated with one can be deallocated with another
- allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
- allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
-
- //The common pool will be destroyed here, since no allocator is
- //attached to the pool
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //The common pool will be destroyed here, since no allocator is
+ //attached to the pool
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_allocator.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_allocator.cpp (original)
+++ trunk/libs/interprocess/example/doc_allocator.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,7 +18,12 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
//Create shared memory
managed_shared_memory segment(create_only,
Deleted: trunk/libs/interprocess/example/doc_anonymous_conditionA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_conditionA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,79 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_conditionA
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <iostream>
-#include <cstdio>
-#include "doc_anonymous_condition_shared_data.hpp"
-
-using namespace boost::interprocess;
-
-int main ()
-{
-
- //Erase previous shared memory
- shared_memory_object::remove("shared_memory");
-
- //Create a shared memory object.
- shared_memory_object shm
- (create_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
- try{
- //Set size
- shm.truncate(sizeof(trace_queue));
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Construct the shared structure in memory
- trace_queue * data = new (addr) trace_queue;
-
- const int NumMsg = 100;
-
- for(int i = 0; i < NumMsg; ++i){
- scoped_lock<interprocess_mutex> lock(data->mutex);
- if(data->message_in){
- data->cond_full.wait(lock);
- }
- if(i == (NumMsg-1))
- std::sprintf(data->items, "%s", "last message");
- else
- std::sprintf(data->items, "%s_%d", "my_trace", i);
-
- //Notify to the other process that there is a message
- data->cond_empty.notify_one();
-
- //Mark message buffer as full
- data->message_in = true;
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
-
- //Erase shared memory
- shared_memory_object::remove("shared_memory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_conditionB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_conditionB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,74 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_conditionB
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <iostream>
-#include <cstring>
-#include "doc_anonymous_condition_shared_data.hpp"
-
-using namespace boost::interprocess;
-
-int main ()
-{
- //Create a shared memory object.
- shared_memory_object shm
- (open_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- try{
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Obtain a pointer to the shared structure
- trace_queue * data = static_cast<trace_queue*>(addr);
-
- //Print messages until the other process marks the end
- bool end_loop = false;
- do{
- scoped_lock<interprocess_mutex> lock(data->mutex);
- if(!data->message_in){
- data->cond_empty.wait(lock);
- }
- if(std::strcmp(data->items, "last message") == 0){
- end_loop = true;
- }
- else{
- //Print the message
- std::cout << data->items << std::endl;
- //Notify the other process that the buffer is empty
- data->message_in = false;
- data->cond_full.notify_one();
- }
- }
- while(!end_loop);
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
-
- //Erase shared memory
- shared_memory_object::remove("shared_memory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_mutexA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_mutexA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,77 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_mutexA
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include "doc_anonymous_mutex_shared_data.hpp"
-#include <iostream>
-#include <cstdio>
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Erase previous shared memory
- shared_memory_object::remove("shared_memory");
-
- //Create a shared memory object.
- shared_memory_object shm
- (create_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- //Set size
- shm.truncate(sizeof(shared_memory_log));
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Construct the shared structure in memory
- shared_memory_log * data = new (addr) shared_memory_log;
-
- //Write some logs
- for(int i = 0; i < shared_memory_log::NumItems; ++i){
- //Lock the mutex
- scoped_lock<interprocess_mutex> lock(data->mutex);
- std::sprintf(data->items[(data->current_line++) % shared_memory_log::NumItems]
- ,"%s_%d", "process_a", i);
- if(i == (shared_memory_log::NumItems-1))
- data->end_a = true;
- //Mutex is released here
- }
-
- //Wait until the other process ends
- while(1){
- scoped_lock<interprocess_mutex> lock(data->mutex);
- if(data->end_b)
- break;
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
- //Erase shared memory
- shared_memory_object::remove("shared_memory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_mutexB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_mutexB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,70 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_mutexB
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include "doc_anonymous_mutex_shared_data.hpp"
-#include <iostream>
-#include <cstdio>
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Open the shared memory object.
- shared_memory_object shm
- (open_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Construct the shared structure in memory
- shared_memory_log * data = static_cast<shared_memory_log*>(addr);
-
- //Write some logs
- for(int i = 0; i < 100; ++i){
- //Lock the mutex
- scoped_lock<interprocess_mutex> lock(data->mutex);
- std::sprintf(data->items[(data->current_line++) % shared_memory_log::NumItems]
- ,"%s_%d", "process_a", i);
- if(i == (shared_memory_log::NumItems-1))
- data->end_b = true;
- //Mutex is released here
- }
-
- //Wait until the other process ends
- while(1){
- scoped_lock<interprocess_mutex> lock(data->mutex);
- if(data->end_a)
- break;
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
- shared_memory_object::remove("shared_memory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_semaphoreA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_semaphoreA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,70 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_semaphoreA
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
-#include "doc_anonymous_semaphore_shared_data.hpp"
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Erase previous shared memory
- shared_memory_object::remove("shared_memory");
-
- //Create a shared memory object.
- shared_memory_object shm
- (create_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- //Set size
- shm.truncate(sizeof(shared_memory_buffer));
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Construct the shared structure in memory
- shared_memory_buffer * data = new (addr) shared_memory_buffer;
-
- const int NumMsg = 100;
-
- //Insert data in the array
- for(int i = 0; i < NumMsg; ++i){
- data->nempty.wait();
- data->mutex.wait();
- data->items[i % shared_memory_buffer::NumItems] = i;
- data->mutex.post();
- data->nstored.post();
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
-
- //Erase shared memory
- shared_memory_object::remove("shared_memory");
-
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_semaphoreB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_semaphoreB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,66 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_semaphoreB
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
-#include "doc_anonymous_semaphore_shared_data.hpp"
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Create a shared memory object.
- shared_memory_object shm
- (open_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Obtain the shared structure
- shared_memory_buffer * data = static_cast<shared_memory_buffer*>(addr);
-
- const int NumMsg = 100;
-
- int extracted_data [NumMsg];
-
- //Extract the data
- for(int i = 0; i < NumMsg; ++i){
- data->nstored.wait();
- data->mutex.wait();
- extracted_data[i] = data->items[i % shared_memory_buffer::NumItems];
- data->mutex.post();
- data->nempty.post();
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
-
- //Erase shared memory
- shared_memory_object::remove("shared_memory");
-
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_upgradable_mutexA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_upgradable_mutexA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,79 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_anonymous_upgradable_mutexA
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include "doc_upgradable_mutex_shared_data.hpp"
-#include <iostream>
-#include <cstdio>
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Erase previous shared memory
- shared_memory_object::remove("shared_memory");
-
- //Create a shared memory object.
- shared_memory_object shm
- (create_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- //Set size
- shm.truncate(sizeof(shared_data));
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Construct the shared structure in memory
- shared_data * data = new (addr) shared_data;
-
- //Write some logs
- for(int i = 0; i < shared_data::NumItems; ++i){
- //Lock the upgradable_mutex
- scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
- std::sprintf(data->items[(data->current_line++) % shared_data::NumItems]
- ,"%s_%d", "process_a", i);
- if(i == (shared_data::NumItems-1))
- data->end_a = true;
- //Mutex is released here
- }
-
- //Wait until the other process ends
- while(1){
- scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
- if(data->end_b)
- break;
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
-
- //Erase shared memory
- shared_memory_object::remove("shared_memory");
-
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_anonymous_upgradable_mutexB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_anonymous_upgradable_mutexB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,72 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-
-//[doc_anonymous_upgradable_mutexB
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include "doc_upgradable_mutex_shared_data.hpp"
-#include <iostream>
-#include <cstdio>
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Open the shared memory object.
- shared_memory_object shm
- (open_only //only create
- ,"shared_memory" //name
- ,read_write //read-write mode
- );
-
- //Map the whole shared memory in this process
- mapped_region region
- (shm //What to map
- ,read_write //Map it as read-write
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
-
- //Construct the shared structure in memory
- shared_data * data = static_cast<shared_data*>(addr);
-
- //Write some logs
- for(int i = 0; i < 100; ++i){
- //Lock the upgradable_mutex
- scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
- std::sprintf(data->items[(data->current_line++) % shared_data::NumItems]
- ,"%s_%d", "process_a", i);
- if(i == (shared_data::NumItems-1))
- data->end_b = true;
- //Mutex is released here
- }
-
- //Wait until the other process ends
- while(1){
- scoped_lock<interprocess_upgradable_mutex> lock(data->upgradable_mutex);
- if(data->end_a)
- break;
- }
- }
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
- }
- shared_memory_object::remove("shared_memory");
- return 0;
-}
-//]
-
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_bufferstream.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_bufferstream.cpp (original)
+++ trunk/libs/interprocess/example/doc_bufferstream.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -14,72 +14,73 @@
#include <boost/interprocess/streams/bufferstream.hpp>
#include <vector>
#include <iterator>
+#include <cstddef>
using namespace boost::interprocess;
int main ()
{
- shared_memory_object::remove("MySharedMemory");
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Fill data
- std::vector<int> data, data2;
- data.reserve(100);
- for(int i = 0; i < 100; ++i){
- data.push_back(i);
- }
-
- //Allocate a buffer in shared memory to write data
- char *my_cstring =
- segment.construct<char>("MyCString")[100*5](0);
- bufferstream mybufstream(my_cstring, 100*5);
-
- //Now write data to the buffer
- for(int i = 0; i < 100; ++i){
- mybufstream << data[i] << std::endl;
- }
-
- //Check there was no overflow attempt
- assert(mybufstream.good());
-
- //Extract all values from the shared memory string
- //directly to a vector.
- data2.reserve(100);
- std::istream_iterator<int> it(mybufstream), itend;
- std::copy(it, itend, std::back_inserter(data2));
-
- //This extraction should have ended will fail error since
- //the numbers formatted in the buffer end before the end
- //of the buffer. (Otherwise it would trigger eofbit)
- assert(mybufstream.fail());
-
- //Compare data
- assert(std::equal(data.begin(), data.end(), data2.begin()));
-
- //Clear errors and rewind
- mybufstream.clear();
- mybufstream.seekp(0, std::ios::beg);
-
- //Now write again the data trying to do a buffer overflow
- for(int i = 0; i < 500; ++i){
- mybufstream << data[i] << std::endl;
- }
-
- //Now make sure badbit is active
- //which means overflow attempt.
- assert(!mybufstream.good());
- assert(mybufstream.bad());
- segment.destroy_ptr(my_cstring);
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Fill data
+ std::vector<int> data;
+ data.reserve(100);
+ for(int i = 0; i < 100; ++i){
+ data.push_back(i);
}
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
+ const std::size_t BufferSize = 100*5;
+
+ //Allocate a buffer in shared memory to write data
+ char *my_cstring =
+ segment.construct<char>("MyCString")[BufferSize](0);
+ bufferstream mybufstream(my_cstring, BufferSize);
+
+ //Now write data to the buffer
+ for(int i = 0; i < 100; ++i){
+ mybufstream << data[i] << std::endl;
}
- shared_memory_object::remove("MySharedMemory");
+
+ //Check there was no overflow attempt
+ assert(mybufstream.good());
+
+ //Extract all values from the shared memory string
+ //directly to a vector.
+ std::vector<int> data2;
+ std::istream_iterator<int> it(mybufstream), itend;
+ std::copy(it, itend, std::back_inserter(data2));
+
+ //This extraction should have ended will fail error since
+ //the numbers formatted in the buffer end before the end
+ //of the buffer. (Otherwise it would trigger eofbit)
+ assert(mybufstream.fail());
+
+ //Compare data
+ assert(std::equal(data.begin(), data.end(), data2.begin()));
+
+ //Clear errors and rewind
+ mybufstream.clear();
+ mybufstream.seekp(0, std::ios::beg);
+
+ //Now write again the data trying to do a buffer overflow
+ for(int i = 0, m = data.size()*5; i < m; ++i){
+ mybufstream << data[i%5] << std::endl;
+ }
+
+ //Now make sure badbit is active
+ //which means overflow attempt.
+ assert(!mybufstream.good());
+ assert(mybufstream.bad());
+ segment.destroy_ptr(my_cstring);
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_cached_adaptive_pool.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_cached_adaptive_pool.cpp (original)
+++ trunk/libs/interprocess/example/doc_cached_adaptive_pool.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,54 +18,53 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Create a cached_adaptive_pool that allocates ints from the managed segment
- //The number of chunks per segment is the default value
- typedef cached_adaptive_pool<int, managed_shared_memory::segment_manager>
- cached_adaptive_pool_t;
- cached_adaptive_pool_t allocator_instance(segment.get_segment_manager());
-
- //The max cached nodes are configurable per instance
- allocator_instance.set_max_cached_nodes(3);
-
- //Create another cached_adaptive_pool. Since the segment manager address
- //is the same, this cached_adaptive_pool will be
- //attached to the same pool so "allocator_instance2" can deallocate
- //nodes allocated by "allocator_instance"
- cached_adaptive_pool_t allocator_instance2(segment.get_segment_manager());
-
- //The max cached nodes are configurable per instance
- allocator_instance2.set_max_cached_nodes(5);
-
- //Create another cached_adaptive_pool using copy-constructor. This
- //cached_adaptive_pool will also be attached to the same pool
- cached_adaptive_pool_t allocator_instance3(allocator_instance2);
-
- //We can clear the cache
- allocator_instance3.deallocate_cache();
-
- //All allocators are equal
- assert(allocator_instance == allocator_instance2);
- assert(allocator_instance2 == allocator_instance3);
-
- //So memory allocated with one can be deallocated with another
- allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
- allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
-
- //The common pool will be destroyed here, since no allocator is
- //attached to the pool
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Create a cached_adaptive_pool that allocates ints from the managed segment
+ //The number of chunks per segment is the default value
+ typedef cached_adaptive_pool<int, managed_shared_memory::segment_manager>
+ cached_adaptive_pool_t;
+ cached_adaptive_pool_t allocator_instance(segment.get_segment_manager());
+
+ //The max cached nodes are configurable per instance
+ allocator_instance.set_max_cached_nodes(3);
+
+ //Create another cached_adaptive_pool. Since the segment manager address
+ //is the same, this cached_adaptive_pool will be
+ //attached to the same pool so "allocator_instance2" can deallocate
+ //nodes allocated by "allocator_instance"
+ cached_adaptive_pool_t allocator_instance2(segment.get_segment_manager());
+
+ //The max cached nodes are configurable per instance
+ allocator_instance2.set_max_cached_nodes(5);
+
+ //Create another cached_adaptive_pool using copy-constructor. This
+ //cached_adaptive_pool will also be attached to the same pool
+ cached_adaptive_pool_t allocator_instance3(allocator_instance2);
+
+ //We can clear the cache
+ allocator_instance3.deallocate_cache();
+
+ //All allocators are equal
+ assert(allocator_instance == allocator_instance2);
+ assert(allocator_instance2 == allocator_instance3);
+
+ //So memory allocated with one can be deallocated with another
+ allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
+ allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
+
+ //The common pool will be destroyed here, since no allocator is
+ //attached to the pool
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_cached_node_allocator.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_cached_node_allocator.cpp (original)
+++ trunk/libs/interprocess/example/doc_cached_node_allocator.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,54 +18,53 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Create a cached_node_allocator that allocates ints from the managed segment
- //The number of chunks per segment is the default value
- typedef cached_node_allocator<int, managed_shared_memory::segment_manager>
- cached_node_allocator_t;
- cached_node_allocator_t allocator_instance(segment.get_segment_manager());
-
- //The max cached nodes are configurable per instance
- allocator_instance.set_max_cached_nodes(3);
-
- //Create another cached_node_allocator. Since the segment manager address
- //is the same, this cached_node_allocator will be
- //attached to the same pool so "allocator_instance2" can deallocate
- //nodes allocated by "allocator_instance"
- cached_node_allocator_t allocator_instance2(segment.get_segment_manager());
-
- //The max cached nodes are configurable per instance
- allocator_instance2.set_max_cached_nodes(5);
-
- //Create another cached_node_allocator using copy-constructor. This
- //cached_node_allocator will also be attached to the same pool
- cached_node_allocator_t allocator_instance3(allocator_instance2);
-
- //We can clear the cache
- allocator_instance3.deallocate_cache();
-
- //All allocators are equal
- assert(allocator_instance == allocator_instance2);
- assert(allocator_instance2 == allocator_instance3);
-
- //So memory allocated with one can be deallocated with another
- allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
- allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
-
- //The common pool will be destroyed here, since no allocator is
- //attached to the pool
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Create a cached_node_allocator that allocates ints from the managed segment
+ //The number of chunks per segment is the default value
+ typedef cached_node_allocator<int, managed_shared_memory::segment_manager>
+ cached_node_allocator_t;
+ cached_node_allocator_t allocator_instance(segment.get_segment_manager());
+
+ //The max cached nodes are configurable per instance
+ allocator_instance.set_max_cached_nodes(3);
+
+ //Create another cached_node_allocator. Since the segment manager address
+ //is the same, this cached_node_allocator will be
+ //attached to the same pool so "allocator_instance2" can deallocate
+ //nodes allocated by "allocator_instance"
+ cached_node_allocator_t allocator_instance2(segment.get_segment_manager());
+
+ //The max cached nodes are configurable per instance
+ allocator_instance2.set_max_cached_nodes(5);
+
+ //Create another cached_node_allocator using copy-constructor. This
+ //cached_node_allocator will also be attached to the same pool
+ cached_node_allocator_t allocator_instance3(allocator_instance2);
+
+ //We can clear the cache
+ allocator_instance3.deallocate_cache();
+
+ //All allocators are equal
+ assert(allocator_instance == allocator_instance2);
+ assert(allocator_instance2 == allocator_instance3);
+
+ //So memory allocated with one can be deallocated with another
+ allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
+ allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
+
+ //The common pool will be destroyed here, since no allocator is
+ //attached to the pool
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_complex_map.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_complex_map.cpp (original)
+++ trunk/libs/interprocess/example/doc_complex_map.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -52,28 +52,31 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
- remove_shared_memory_on_destroy remove_on_destroy("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
{
- //Create shared memory
- managed_shared_memory segment(create_only,"MySharedMemory", 65536);
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
- //An allocator convertible to any allocator<T, segment_manager_t> type
- void_allocator alloc_inst (segment.get_segment_manager());
+ //Create shared memory
+ managed_shared_memory segment(create_only,"MySharedMemory", 65536);
- //Construct the shared memory map and fill it
- complex_map_type *mymap = segment.construct<complex_map_type>
- //(object name), (first ctor parameter, second ctor parameter)
- ("MyMap")(std::less<char_string>(), alloc_inst);
+ //An allocator convertible to any allocator<T, segment_manager_t> type
+ void_allocator alloc_inst (segment.get_segment_manager());
- for(int i = 0; i < 100; ++i){
- //Both key(string) and value(complex_data) need an allocator in their constructors
- char_string key_object(alloc_inst);
- complex_data mapped_object(i, "default_name", alloc_inst);
- map_value_type value(key_object, mapped_object);
- //Modify values and insert them in the map
- mymap->insert(value);
- }
+ //Construct the shared memory map and fill it
+ complex_map_type *mymap = segment.construct<complex_map_type>
+ //(object name), (first ctor parameter, second ctor parameter)
+ ("MyMap")(std::less<char_string>(), alloc_inst);
+
+ for(int i = 0; i < 100; ++i){
+ //Both key(string) and value(complex_data) need an allocator in their constructors
+ char_string key_object(alloc_inst);
+ complex_data mapped_object(i, "default_name", alloc_inst);
+ map_value_type value(key_object, mapped_object);
+ //Modify values and insert them in the map
+ mymap->insert(value);
}
return 0;
}
Modified: trunk/libs/interprocess/example/doc_cont.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_cont.cpp (original)
+++ trunk/libs/interprocess/example/doc_cont.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,48 +17,47 @@
int main ()
{
using namespace boost::interprocess;
- shared_memory_object::remove("MySharedMemory");
- try{
- //A managed shared memory where we can construct objects
- //associated with a c-string
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Alias an STL-like allocator of ints that allocates ints from the segment
- typedef allocator<int, managed_shared_memory::segment_manager>
- ShmemAllocator;
-
- //Alias a vector that uses the previous STL-like allocator
- typedef vector<int, ShmemAllocator> MyVector;
-
- int initVal[] = {0, 1, 2, 3, 4, 5, 6 };
- const int *begVal = initVal;
- const int *endVal = initVal + sizeof(initVal)/sizeof(initVal[0]);
-
- //Initialize the STL-like allocator
- const ShmemAllocator alloc_inst (segment.get_segment_manager());
-
- //Construct the vector in the shared memory segment with the STL-like allocator
- //from a range of iterators
- MyVector *myvector =
- segment.construct<MyVector>
- ("MyVector")/*object name*/
- (begVal /*first ctor parameter*/,
- endVal /*second ctor parameter*/,
- alloc_inst /*third ctor parameter*/);
-
- //Use vector as your want
- std::sort(myvector->rbegin(), myvector->rend());
- // . . .
- //When done, destroy and delete vector from the segment
- segment.destroy<MyVector>("MyVector");
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //A managed shared memory where we can construct objects
+ //associated with a c-string
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Alias an STL-like allocator of ints that allocates ints from the segment
+ typedef allocator<int, managed_shared_memory::segment_manager>
+ ShmemAllocator;
+
+ //Alias a vector that uses the previous STL-like allocator
+ typedef vector<int, ShmemAllocator> MyVector;
+
+ int initVal[] = {0, 1, 2, 3, 4, 5, 6 };
+ const int *begVal = initVal;
+ const int *endVal = initVal + sizeof(initVal)/sizeof(initVal[0]);
+
+ //Initialize the STL-like allocator
+ const ShmemAllocator alloc_inst (segment.get_segment_manager());
+
+ //Construct the vector in the shared memory segment with the STL-like allocator
+ //from a range of iterators
+ MyVector *myvector =
+ segment.construct<MyVector>
+ ("MyVector")/*object name*/
+ (begVal /*first ctor parameter*/,
+ endVal /*second ctor parameter*/,
+ alloc_inst /*third ctor parameter*/);
+
+ //Use vector as your want
+ std::sort(myvector->rbegin(), myvector->rend());
+ // . . .
+ //When done, destroy and delete vector from the segment
+ segment.destroy<MyVector>("MyVector");
return 0;
}
//]
Deleted: trunk/libs/interprocess/example/doc_contA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_contA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,60 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-//[doc_contA
-#include <boost/interprocess/managed_shared_memory.hpp>
-#include <boost/interprocess/containers/vector.hpp>
-#include <boost/interprocess/allocators/allocator.hpp>
-
-int main ()
-{
- using namespace boost::interprocess;
- try{
- //Shared memory front-end that is able to construct objects
- //associated with a c-string. Erase previous shared memory with the name
- //to be used and create the memory segment at the specified address and initialize resources
- shared_memory_object::remove("MySharedMemory");
- managed_shared_memory segment
- (create_only
- ,"MySharedMemory" //segment name
- ,65536); //segment size in bytes
-
- //Alias an STL compatible allocator of ints that allocates ints from the managed
- //shared memory segment. This allocator will allow to place containers
- //in managed shared memory segments
- typedef allocator<int, managed_shared_memory::segment_manager>
- ShmemAllocator;
-
- //Alias a vector that uses the previous STL-like allocator
- typedef vector<int, ShmemAllocator> MyVector;
-
- //Initialize shared memory STL-compatible allocator
- const ShmemAllocator alloc_inst (segment.get_segment_manager());
-
- //Construct a shared memory
- MyVector *myvector =
- segment.construct<MyVector>("MyVector") //object name
- (alloc_inst);//first ctor parameter
-
- //Insert data in the vector
- for(int i = 0; i < 100; ++i){
- myvector->push_back(i);
- }
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_contB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_contB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,57 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-//[doc_contB
-#include <boost/interprocess/managed_shared_memory.hpp>
-#include <boost/interprocess/containers/vector.hpp>
-#include <boost/interprocess/allocators/allocator.hpp>
-#include <algorithm>
-
-int main ()
-{
- using namespace boost::interprocess;
- try{
- //A special shared memory where we can
- //construct objects associated with a name.
- //Connect to the already created shared memory segment
- //and initialize needed resources
- managed_shared_memory segment
- (open_only
- ,"MySharedMemory"); //segment name
-
- //Alias an STL compatible allocator of ints that allocates ints from the managed
- //shared memory segment. This allocator will allow to place containers
- //in managed shared memory segments
- typedef allocator<int, managed_shared_memory::segment_manager>
- ShmemAllocator;
-
- //Alias a vector that uses the previous STL-like allocator
- typedef vector<int, ShmemAllocator> MyVector;
-
- //Find the vector using the c-string name
- MyVector *myvector = segment.find<MyVector>("MyVector").first;
-
- //Use vector in reverse order
- std::sort(myvector->rbegin(), myvector->rend());
- // . . .
-
- //When done, destroy the vector from the segment
- segment.destroy<MyVector>("MyVector");
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_file_mapping.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_file_mapping.cpp (original)
+++ trunk/libs/interprocess/example/doc_file_mapping.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -13,35 +13,36 @@
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include <fstream>
+#include <string>
+#include <vector>
#include <cstring>
#include <cstddef>
-#include <cstdio> //std::remove
+#include <cstdlib>
-int main ()
+int main(int argc, char *argv[])
{
using namespace boost::interprocess;
- try{
- //Create a file
- std::filebuf fbuf;
- fbuf.open("file.bin", std::ios_base::in | std::ios_base::out
- | std::ios_base::trunc | std::ios_base::binary);
-
- //Set the size
- fbuf.pubseekoff(9999, std::ios_base::beg);
- fbuf.sputc(0);
- fbuf.close();
+ const std::size_t FileSize = 10000;
+ if(argc == 1){ //Parent process executes this
+ { //Create a file
+ std::filebuf fbuf;
+ fbuf.open("file.bin", std::ios_base::in | std::ios_base::out
+ | std::ios_base::trunc | std::ios_base::binary);
+ //Set the size
+ fbuf.pubseekoff(FileSize-1, std::ios_base::beg);
+ fbuf.sputc(0);
+ }
+ //Remove file on exit
+ struct file_remove
+ {
+ ~file_remove (){ file_mapping::remove("file.bin"); }
+ } destroy_on_exit;
- //Create a file mapping.
+ //Create a file mapping
file_mapping m_file("file.bin", read_write);
- //Map the whole file in this process
- mapped_region region
- (m_file //What to map
- ,read_write //Map it as read-write
- );
-
- if(region.get_size() != 10000)
- return 1;
+ //Map the whole file with read-write permissions in this process
+ mapped_region region(m_file, read_write);
//Get the address of the mapped region
void * addr = region.get_address();
@@ -50,12 +51,42 @@
//Write all the memory to 1
std::memset(addr, 1, size);
+ //Launch child process
+ std::string s(argv[0]); s += " child";
+ if(0 != std::system(s.c_str()))
+ return 1;
}
- catch(interprocess_exception &ex){
- std::remove("file.bin");
- std::cout << ex.what() << std::endl;
- return 1;
+ else{ //Child process executes this
+ { //Open the file mapping and map it as read-only
+ file_mapping m_file ("file.bin", read_only);
+ mapped_region region(m_file, read_only);
+
+ //Get the address of the mapped region
+ void * addr = region.get_address();
+ std::size_t size = region.get_size();
+
+ //Check that memory was initialized to 1
+ const char *mem = static_cast<char*>(addr);
+ for(std::size_t i = 0; i < size; ++i)
+ if(*mem++ != 1)
+ return 1; //Error checking memory
+ }
+ { //Now test it reading the file
+ std::filebuf fbuf;
+ fbuf.open("file.bin", std::ios_base::in | std::ios_base::binary);
+
+ //Read it to memory
+ std::vector<char> vect(FileSize, 0);
+ fbuf.sgetn(&vect[0], std::streamsize(vect.size()));
+
+ //Check that memory was initialized to 1
+ const char *mem = static_cast<char*>(&vect[0]);
+ for(std::size_t i = 0; i < FileSize; ++i)
+ if(*mem++ != 1)
+ return 1; //Error checking memory
+ }
}
+
return 0;
}
//]
Deleted: trunk/libs/interprocess/example/doc_file_mapping2.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_file_mapping2.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,74 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_file_mapping2
-#include <boost/interprocess/file_mapping.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
-#include <fstream>
-#include <cstddef>
-#include <cstdio> //std::remove
-#include <vector>
-
-int main ()
-{
- using namespace boost::interprocess;
- try{
- //Open the file mapping
- file_mapping m_file ("file.bin", read_only);
-
- //Map the whole file in this process
- mapped_region region
- (m_file //What to map
- ,read_only //Map it as read-only
- );
-
- //Get the address of the mapped region
- void * addr = region.get_address();
- std::size_t size = region.get_size();
-
- //Check that memory was initialized to 1
- const char *mem = static_cast<char*>(addr);
- for(std::size_t i = 0; i < size; ++i){
- if(*mem++ != 1){
- std::cout << "Error checking memory!" << std::endl;
- return 1;
- }
- }
-
- //Now test it reading the file
- std::filebuf fbuf;
- fbuf.open("file.bin", std::ios_base::in | std::ios_base::binary);
-
- //Read it to memory
- std::vector<char> vect(region.get_size(), 0);
- fbuf.sgetn(&vect[0], std::streamsize(vect.size()));
-
- //Check that memory was initialized to 1
- mem = static_cast<char*>(&vect[0]);
- for(std::size_t i = 0; i < size; ++i){
- if(*mem++ != 1){
- std::cout << "Error checking memory!" << std::endl;
- return 1;
- }
- }
-
- std::cout << "Test successful!" << std::endl;
- }
- catch(interprocess_exception &ex){
- std::remove("file.bin");
- std::cout << "Unexpected exception: " << ex.what() << std::endl;
- return 1;
- }
- std::remove("file.bin");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_intrusive.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_intrusive.cpp (original)
+++ trunk/libs/interprocess/example/doc_intrusive.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -7,6 +7,7 @@
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
+
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
//[doc_intrusive
@@ -68,42 +69,40 @@
: m_intrusive_ptr(ptr){}
};
-int main ()
+int main()
{
- shared_memory_object::remove("my_shmem");
-
- try{
- //Create shared memory
- managed_shared_memory shmem(create_only, "my_shmem", 10000);
-
- //Create the unique reference counted object in shared memory
- N::reference_counted_class *ref_counted =
- shmem.construct<N::reference_counted_class>
- ("ref_counted")(shmem.get_segment_manager());
-
- //Create an array of ten intrusive pointer owners in shared memory
- intrusive_ptr_owner *intrusive_owner_array =
- shmem.construct<intrusive_ptr_owner>
- (anonymous_instance)[10](ref_counted);
-
- //Now test that reference count is ten
- if(ref_counted->use_count() != 10)
- return 1;
-
- //Now destroy the array of intrusive pointer owners
- //This should destroy every intrusive_ptr and because of
- //that reference_counted_class will be destroyed
- shmem.destroy_ptr(intrusive_owner_array);
-
- //Now the reference counted object should have been destroyed
- if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
- return 1;
- }
- catch(...){
- shared_memory_object::remove("my_shmem");
- throw;
- }
- shared_memory_object::remove("my_shmem");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
+
+ //Create the unique reference counted object in shared memory
+ N::reference_counted_class *ref_counted =
+ shmem.construct<N::reference_counted_class>
+ ("ref_counted")(shmem.get_segment_manager());
+
+ //Create an array of ten intrusive pointer owners in shared memory
+ intrusive_ptr_owner *intrusive_owner_array =
+ shmem.construct<intrusive_ptr_owner>
+ (anonymous_instance)[10](ref_counted);
+
+ //Now test that reference count is ten
+ if(ref_counted->use_count() != 10)
+ return 1;
+
+ //Now destroy the array of intrusive pointer owners
+ //This should destroy every intrusive_ptr and because of
+ //that reference_counted_class will be destroyed
+ shmem.destroy_ptr(intrusive_owner_array);
+
+ //Now the reference counted object should have been destroyed
+ if(shmem.find<intrusive_ptr_owner>("ref_counted").first)
+ return 1;
//Success!
return 0;
}
Added: trunk/libs/interprocess/example/doc_ipc_message.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/doc_ipc_message.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,72 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+//[run_ipc_message
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <cstdlib> //std::system
+#include <sstream>
+
+int main (int argc, char *argv[])
+{
+ using namespace boost::interprocess;
+ if(argc == 1){ //Parent process
+ //Remove shared memory on construction and destruction
+ struct shm_remove
+ {
+ shm_remove() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a managed shared memory segment
+ managed_shared_memory segment(create_only, "MySharedMemory", 65536);
+
+ //Allocate a portion of the segment (raw memory)
+ std::size_t free_memory = segment.get_free_memory();
+ void * shptr = segment.allocate(1024/*bytes to allocate*/);
+
+ //Check invariant
+ if(free_memory <= segment.get_free_memory())
+ return 1;
+
+ //An handle from the base address can identify any byte of the shared
+ //memory segment even if it is mapped in different base addresses
+ managed_shared_memory::handle_t handle = segment.get_handle_from_address(shptr);
+ std::stringstream s;
+ s << argv[0] << " " << handle << std::ends;
+
+ //Launch child process
+ if(0 != std::system(s.str().c_str()))
+ return 1;
+ //Check memory has been freed
+ if(free_memory != segment.get_free_memory())
+ return 1;
+ }
+ else{
+ //Open managed segment
+ managed_shared_memory segment(open_only, "MySharedMemory");
+
+ //An handle from the base address can identify any byte of the shared
+ //memory segment even if it is mapped in different base addresses
+ managed_shared_memory::handle_t handle = 0;
+
+ //Obtain handle value
+ std::stringstream s; s << argv[1]; s >> handle;
+
+ //Get buffer local address from handle
+ void *msg = segment.get_address_from_handle(handle);
+
+ //Deallocate previously allocated memory
+ segment.deallocate(msg);
+ }
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_ipc_messageA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_ipc_messageA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,55 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-//[doc_ipc_messageA
-#include <boost/interprocess/managed_shared_memory.hpp>
-
-int main ()
-{
- using namespace boost::interprocess;
-
- //A special shared memory from which we are
- //able to allocate raw memory buffers.
- //First remove any old shared memory of the same name, create
- //the shared memory segment and initialize needed resources
- shared_memory_object::remove("MySharedMemory");
- try{
- managed_shared_memory segment
- (create_only,
- "MySharedMemory", //segment name
- 65536); //segment size in bytes
-
- //Allocate a portion of the segment
- void * shptr = segment.allocate(1024/*bytes to allocate*/);
-
- //An handle from the base address can identify any byte of the shared
- //memory segment even if it is mapped in different base addresses
- managed_shared_memory::handle_t handle = segment.get_handle_from_address(shptr);
- (void)handle;
- // Copy message to buffer
- // . . .
- // Send handle to other process
- // . . .
- // Wait response from other process
- // . . .
-
- //Deallocate the portion previously allocated
- segment.deallocate(shptr);
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_ipc_messageB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_ipc_messageB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,47 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-//[doc_ipc_messageB
-#include <boost/interprocess/managed_shared_memory.hpp>
-
-int main ()
-{
- using namespace boost::interprocess;
-
- try{
- //A special shared memory from which we are
- //able to allocate raw memory buffers.
- //Connect to the already created shared memory segment
- //and initialize needed resources
- managed_shared_memory segment(open_only, "MySharedMemory"); //segment name
-
- //An handle from the base address can identify any byte of the shared
- //memory segment even if it is mapped in different base addresses
- managed_shared_memory::handle_t handle = 0;
-
- //Wait handle msg from the other process and put it in
- //"handle" local variable
- //Get buffer local address from handle
- void *msg = segment.get_address_from_handle(handle);
- (void)msg;
- //Do anything with msg
- //. . .
- //Send ack to sender process
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_managed_aligned_allocation.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_aligned_allocation.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_aligned_allocation.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -16,53 +16,52 @@
{
using namespace boost::interprocess;
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
//Managed memory segment that allocates portions of a shared memory
//segment with the default management algorithm
- shared_memory_object::remove("MyManagedShm");
+ managed_shared_memory managed_shm(create_only, "MySharedMemory", 65536);
- try{
- managed_shared_memory managed_shm(create_only, "MyManagedShm", 65536);
+ const std::size_t Alignment = 128;
- const std::size_t Alignment = 128;
+ //Allocate 100 bytes aligned to Alignment from segment, throwing version
+ void *ptr = managed_shm.allocate_aligned(100, Alignment);
- //Allocate 100 bytes aligned to Alignment from segment, throwing version
- void *ptr = managed_shm.allocate_aligned(100, Alignment);
+ //Check alignment
+ assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
- //Check alignment
- assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
+ //Deallocate it
+ managed_shm.deallocate(ptr);
- //Deallocate it
- managed_shm.deallocate(ptr);
+ //Non throwing version
+ ptr = managed_shm.allocate_aligned(100, Alignment, std::nothrow);
- //Non throwing version
- ptr = managed_shm.allocate_aligned(100, Alignment, std::nothrow);
+ //Check alignment
+ assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
- //Check alignment
- assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
+ //Deallocate it
+ managed_shm.deallocate(ptr);
- //Deallocate it
- managed_shm.deallocate(ptr);
+ //If we want to efficiently allocate aligned blocks of memory
+ //use managed_shared_memory::PayloadPerAllocation value
+ assert(Alignment > managed_shared_memory::PayloadPerAllocation);
- //If we want to efficiently allocate aligned blocks of memory
- //use managed_shared_memory::PayloadPerAllocation value
- assert(Alignment > managed_shared_memory::PayloadPerAllocation);
+ //This allocation will maximize the size of the aligned memory
+ //and will increase the possibility of finding more aligned memory
+ ptr = managed_shm.allocate_aligned
+ (3*Alignment - managed_shared_memory::PayloadPerAllocation, Alignment);
- //This allocation will maximize the size of the aligned memory
- //and will increase the possibility of finding more aligned memory
- ptr = managed_shm.allocate_aligned
- (3*Alignment - managed_shared_memory::PayloadPerAllocation, Alignment);
+ //Check alignment
+ assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
- //Check alignment
- assert((static_cast<char*>(ptr)-static_cast<char*>(0)) % Alignment == 0);
+ //Deallocate it
+ managed_shm.deallocate(ptr);
- //Deallocate it
- managed_shm.deallocate(ptr);
- }
- catch(...){
- shared_memory_object::remove("MyManagedShm");
- throw;
- }
- shared_memory_object::remove("MyManagedShm");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_managed_allocation_command.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_allocation_command.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_allocation_command.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -16,73 +16,71 @@
{
using namespace boost::interprocess;
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
//Managed memory segment that allocates portions of a shared memory
//segment with the default management algorithm
- shared_memory_object::remove("MyManagedShm");
+ managed_shared_memory managed_shm(create_only, "MySharedMemory", 10000*sizeof(std::size_t));
- try{
- managed_shared_memory managed_shm(create_only, "MyManagedShm", 10000*sizeof(std::size_t));
+ //Allocate at least 100 bytes, 1000 bytes if possible
+ std::size_t received_size, min_size = 100, preferred_size = 1000;
+ std::size_t *ptr = managed_shm.allocation_command<std::size_t>
+ (boost::interprocess::allocate_new, min_size, preferred_size, received_size).first;
+
+ //Received size must be bigger than min_size
+ assert(received_size >= min_size);
+
+ //Get free memory
+ std::size_t free_memory_after_allocation = managed_shm.get_free_memory();
+
+ //Now write the data
+ for(std::size_t i = 0; i < received_size; ++i) ptr[i] = i;
+
+ //Now try to triplicate the buffer. We won't admit an expansion
+ //lower to the double of the original buffer.
+ //This "should" be successful since no other class is allocating
+ //memory from the segment
+ std::size_t expanded_size;
+ std::pair<std::size_t *, bool> ret = managed_shm.allocation_command
+ (boost::interprocess::expand_fwd, received_size*2, received_size*3, expanded_size, ptr);
+
+ //Check invariants
+ assert(ret.second == true);
+ assert(ret.first == ptr);
+ assert(expanded_size >= received_size*2);
+
+ //Get free memory and compare
+ std::size_t free_memory_after_expansion = managed_shm.get_free_memory();
+ assert(free_memory_after_expansion < free_memory_after_allocation);
+
+ //Write new values
+ for(std::size_t i = received_size; i < expanded_size; ++i) ptr[i] = i;
+
+ //Try to shrink approximately to min_size, but the new size
+ //should be smaller than min_size*2.
+ //This "should" be successful since no other class is allocating
+ //memory from the segment
+ std::size_t shrunk_size;
+ ret = managed_shm.allocation_command
+ (boost::interprocess::shrink_in_place, min_size*2, min_size, shrunk_size, ptr);
+
+ //Check invariants
+ assert(ret.second == true);
+ assert(ret.first == ptr);
+ assert(shrunk_size <= min_size*2);
+ assert(shrunk_size >= min_size);
+
+ //Get free memory and compare
+ std::size_t free_memory_after_shrinking = managed_shm.get_free_memory();
+ assert(free_memory_after_shrinking > free_memory_after_expansion);
- //Allocate at least 100 bytes, 1000 bytes if possible
- std::size_t received_size, min_size = 100, preferred_size = 1000;
- std::size_t *ptr = managed_shm.allocation_command<std::size_t>
- (allocate_new, min_size, preferred_size, received_size).first;
-
- //Received size must be bigger than min_size
- assert(received_size >= min_size);
-
- //Get free memory
- std::size_t free_memory_after_allocation = managed_shm.get_free_memory();
-
- //Now write the data
- for(std::size_t i = 0; i < received_size; ++i) ptr[i] = i;
-
- //Now try to triplicate the buffer. We won't admit an expansion
- //lower to the double of the original buffer.
- //This "should" be successful since no other class is allocating
- //memory from the segment
- std::size_t expanded_size;
- std::pair<std::size_t *, bool> ret = managed_shm.allocation_command
- (expand_fwd, received_size*2, received_size*3, expanded_size, ptr);
-
- //Check invariants
- assert(ret.second == true);
- assert(ret.first == ptr);
- assert(expanded_size >= received_size*2);
-
- //Get free memory and compare
- std::size_t free_memory_after_expansion = managed_shm.get_free_memory();
- assert(free_memory_after_expansion < free_memory_after_allocation);
-
- //Write new values
- for(std::size_t i = received_size; i < expanded_size; ++i) ptr[i] = i;
-
- //Try to shrink approximately to min_size, but the new size
- //should be smaller than min_size*2.
- //This "should" be successful since no other class is allocating
- //memory from the segment
- std::size_t shrunk_size;
- ret = managed_shm.allocation_command
- (shrink_in_place, min_size*2, min_size, shrunk_size, ptr);
-
- //Check invariants
- assert(ret.second == true);
- assert(ret.first == ptr);
- assert(shrunk_size <= min_size*2);
- assert(shrunk_size >= min_size);
-
- //Get free memory and compare
- std::size_t free_memory_after_shrinking = managed_shm.get_free_memory();
- assert(free_memory_after_shrinking > free_memory_after_expansion);
-
- //Deallocate the buffer
- managed_shm.deallocate(ptr);
- }
- catch(...){
- shared_memory_object::remove("MyManagedShm");
- throw;
- }
- shared_memory_object::remove("MyManagedShm");
+ //Deallocate the buffer
+ managed_shm.deallocate(ptr);
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_managed_construction_info.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_construction_info.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_construction_info.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,41 +21,39 @@
int main()
{
using namespace boost::interprocess;
- typedef managed_shared_memory msm;
- shared_memory_object::remove("MyManagedShm");
- try{
- msm managed_shm(create_only, "MyManagedShm", 10000*sizeof(std::size_t));
-
- //Construct objects
- my_class *named_object = managed_shm.construct<my_class>("Object name")[1]();
- my_class *unique_object = managed_shm.construct<my_class>(unique_instance)[2]();
- my_class *anon_object = managed_shm.construct<my_class>(anonymous_instance)[3]();
-
- //Now test "get_instance_name" function.
- assert(0 == std::strcmp(msm::get_instance_name(named_object), "Object name"));
- assert(0 == msm::get_instance_name(unique_object));
- assert(0 == msm::get_instance_name(anon_object));
-
- //Now test "get_instance_type" function.
- assert(named_type == msm::get_instance_type(named_object));
- assert(unique_type == msm::get_instance_type(unique_object));
- assert(anonymous_type == msm::get_instance_type(anon_object));
-
- //Now test "get_instance_length" function.
- assert(1 == msm::get_instance_length(named_object));
- assert(2 == msm::get_instance_length(unique_object));
- assert(3 == msm::get_instance_length(anon_object));
-
- managed_shm.destroy_ptr(named_object);
- managed_shm.destroy_ptr(unique_object);
- managed_shm.destroy_ptr(anon_object);
- }
- catch(...){
- shared_memory_object::remove("MyManagedShm");
- throw;
- }
- shared_memory_object::remove("MyManagedShm");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ managed_shared_memory managed_shm(create_only, "MySharedMemory", 10000*sizeof(std::size_t));
+
+ //Construct objects
+ my_class *named_object = managed_shm.construct<my_class>("Object name")[1]();
+ my_class *unique_object = managed_shm.construct<my_class>(unique_instance)[2]();
+ my_class *anon_object = managed_shm.construct<my_class>(anonymous_instance)[3]();
+
+ //Now test "get_instance_name" function.
+ assert(0 == std::strcmp(managed_shared_memory::get_instance_name(named_object), "Object name"));
+ assert(0 == managed_shared_memory::get_instance_name(unique_object));
+ assert(0 == managed_shared_memory::get_instance_name(anon_object));
+
+ //Now test "get_instance_type" function.
+ assert(named_type == managed_shared_memory::get_instance_type(named_object));
+ assert(unique_type == managed_shared_memory::get_instance_type(unique_object));
+ assert(anonymous_type == managed_shared_memory::get_instance_type(anon_object));
+
+ //Now test "get_instance_length" function.
+ assert(1 == managed_shared_memory::get_instance_length(named_object));
+ assert(2 == managed_shared_memory::get_instance_length(unique_object));
+ assert(3 == managed_shared_memory::get_instance_length(anon_object));
+
+ managed_shm.destroy_ptr(named_object);
+ managed_shm.destroy_ptr(unique_object);
+ managed_shm.destroy_ptr(anon_object);
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_managed_copy_on_write.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_copy_on_write.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_copy_on_write.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -11,7 +11,6 @@
//[doc_managed_copy_on_write
#include <boost/interprocess/managed_mapped_file.hpp>
#include <fstream> //std::fstream
-#include <cstdio> //std::remove
#include <iterator>//std::distance
int main()
@@ -19,8 +18,8 @@
using namespace boost::interprocess;
//Try to erase any previous managed segment with the same name
- std::remove("MyManagedFile");
- std::remove("MyManagedFile2");
+ file_mapping::remove("MyManagedFile");
+ file_mapping::remove("MyManagedFile2");
remove_file_on_destroy destroyer1("MyManagedFile");
remove_file_on_destroy destroyer2("MyManagedFile2");
Modified: trunk/libs/interprocess/example/doc_managed_external_buffer.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_external_buffer.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_external_buffer.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -43,7 +43,9 @@
//be stored in the static_buffer!
MyBufferList *list = objects_in_static_memory.construct<MyBufferList>(L"MyList")
(objects_in_static_memory.get_segment_manager());
-
+ //<-
+ (void)list;
+ //->
//Since the allocation algorithm from wmanaged_external_buffer uses relative
//pointers and all the pointers constructed int the static memory point
//to objects in the same segment, we can create another static buffer
Modified: trunk/libs/interprocess/example/doc_managed_grow.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_grow.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_grow.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,48 +21,49 @@
int main()
{
using namespace boost::interprocess;
- try{
- { //Remove old shared memory if present
- shared_memory_object::remove("MyManagedShm");
- //Create a managed shared memory
- managed_shared_memory shm(create_only, "MyManagedShm", 1000);
- //Check size
- assert(shm.get_size() == 1000);
- //Construct a named object
- MyClass *myclass = shm.construct<MyClass>("MyClass")();
- //The managed segment is unmapped here
- }
- {
- //Now that the segment is not mapped grow it adding extra 500 bytes
- managed_shared_memory::grow("MyManagedShm", 500);
- //Map it again
- managed_shared_memory shm(open_only, "MyManagedShm");
- //Check size
- assert(shm.get_size() == 1500);
- //Check "MyClass" is still there
- MyClass *myclass = shm.find<MyClass>("MyClass").first;
- assert(myclass != 0);
- //The managed segment is unmapped here
- }
- {
- //Now minimize the size of the segment
- managed_shared_memory::shrink_to_fit("MyManagedShm");
- //Map it again
- managed_shared_memory shm(open_only, "MyManagedShm");
- //Check size
- assert(shm.get_size() < 1000);
- //Check "MyClass" is still there
- MyClass *myclass = shm.find<MyClass>("MyClass").first;
- assert(myclass != 0);
- //The managed segment is unmapped here
- }
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ {
+ //Create a managed shared memory
+ managed_shared_memory shm(create_only, "MySharedMemory", 1000);
+ //Check size
+ assert(shm.get_size() == 1000);
+ //Construct a named object
+ MyClass *myclass = shm.construct<MyClass>("MyClass")();
+ //The managed segment is unmapped here
+ //<-
+ (void)myclass;
+ //->
}
- catch(...){
- shared_memory_object::remove("MyManagedShm");
- throw;
+ {
+ //Now that the segment is not mapped grow it adding extra 500 bytes
+ managed_shared_memory::grow("MySharedMemory", 500);
+ //Map it again
+ managed_shared_memory shm(open_only, "MySharedMemory");
+ //Check size
+ assert(shm.get_size() == 1500);
+ //Check "MyClass" is still there
+ MyClass *myclass = shm.find<MyClass>("MyClass").first;
+ assert(myclass != 0);
+ //The managed segment is unmapped here
+ }
+ {
+ //Now minimize the size of the segment
+ managed_shared_memory::shrink_to_fit("MySharedMemory");
+ //Map it again
+ managed_shared_memory shm(open_only, "MySharedMemory");
+ //Check size
+ assert(shm.get_size() < 1000);
+ //Check "MyClass" is still there
+ MyClass *myclass = shm.find<MyClass>("MyClass").first;
+ assert(myclass != 0);
+ //The managed segment is unmapped here
}
- //Remove the managed segment
- shared_memory_object::remove("MyManagedShm");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_managed_mapped_file.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_mapped_file.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_mapped_file.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -24,59 +24,67 @@
{
const char *FileName = "file_mapping";
const std::size_t FileSize = 1000;
- std::remove(FileName);
+ file_mapping::remove(FileName);
try{
- managed_mapped_file mfile_memory(create_only, FileName, FileSize);
- MyList * mylist = mfile_memory.construct<MyList>("MyList")
- (mfile_memory.get_segment_manager());
-
- //Obtain handle, that identifies the list in the buffer
- managed_mapped_file::handle_t list_handle = mfile_memory.get_handle_from_address(mylist);
-
- //Fill list until there is no more room in the file
- try{
- while(1) {
- mylist->insert(mylist->begin(), 0);
+ std::size_t old_size = 0;
+ managed_mapped_file::handle_t list_handle;
+ {
+ managed_mapped_file mfile_memory(create_only, FileName, FileSize);
+ MyList *mylist = mfile_memory.construct<MyList>("MyList")
+ (mfile_memory.get_segment_manager());
+
+ //Obtain handle, that identifies the list in the buffer
+ list_handle = mfile_memory.get_handle_from_address(mylist);
+
+ //Fill list until there is no more room in the file
+ try{
+ while(1) {
+ mylist->insert(mylist->begin(), 0);
+ }
}
+ catch(const bad_alloc &){
+ //mapped file is full
+ }
+ //Let's obtain the size of the list
+ old_size = mylist->size();
}
- catch(const bad_alloc &){
- //mapped file is full
- }
- //Let's obtain the size of the list
- std::size_t old_size = mylist->size();
-
//To make the list bigger, let's increase the mapped file
//in FileSize bytes more.
- //mfile_memory.grow(FileSize);
+ managed_mapped_file::grow(FileName, FileSize*2);
+
+ {
+ managed_mapped_file mfile_memory(open_only, FileName);
+
- //If mapping address has changed, the old pointer is invalid,
- //so use previously obtained handle to find the new pointer.
- mylist = static_cast<MyList *>
- (mfile_memory.get_address_from_handle(list_handle));
-
- //Fill list until there is no more room in the file
- try{
- while(1) {
- mylist->insert(mylist->begin(), 0);
+ //If mapping address has changed, the old pointer is invalid,
+ //so use previously obtained handle to find the new pointer.
+ MyList *mylist = static_cast<MyList *>
+ (mfile_memory.get_address_from_handle(list_handle));
+
+ //Fill list until there is no more room in the file
+ try{
+ while(1) {
+ mylist->insert(mylist->begin(), 0);
+ }
+ }
+ catch(const bad_alloc &){
+ //mapped file is full
}
- }
- catch(const bad_alloc &){
- //mapped file is full
- }
- //Let's obtain the new size of the list
- std::size_t new_size = mylist->size();
+ //Let's obtain the new size of the list
+ std::size_t new_size = mylist->size();
- assert(new_size > old_size);
+ assert(new_size > old_size);
- //Destroy list
- mfile_memory.destroy_ptr(mylist);
+ //Destroy list
+ mfile_memory.destroy_ptr(mylist);
+ }
}
catch(...){
- std::remove(FileName);
+ file_mapping::remove(FileName);
throw;
}
- std::remove(FileName);
+ file_mapping::remove(FileName);
return 0;
}
Modified: trunk/libs/interprocess/example/doc_managed_multiple_allocation.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_multiple_allocation.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_multiple_allocation.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -10,69 +10,59 @@
#include <boost/interprocess/detail/config_begin.hpp>
//[doc_managed_multiple_allocation
#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/detail/move.hpp> //boost::interprocess::move
#include <cassert>//assert
#include <cstring>//std::memset
#include <new> //std::nothrow
#include <vector> //std::vector
+
int main()
{
using namespace boost::interprocess;
- typedef managed_shared_memory::multiallocation_iterator multiallocation_iterator;
-
- //Try to erase any previous managed segment with the same name
- shared_memory_object::remove("MyManagedShm");
-
- try{
- managed_shared_memory managed_shm(create_only, "MyManagedShm", 65536);
+ typedef managed_shared_memory::multiallocation_chain multiallocation_chain;
- //Allocate 16 elements of 100 bytes in a single call. Non-throwing version.
- multiallocation_iterator beg_it = managed_shm.allocate_many(100, 16, std::nothrow);
-
- //To check for an error, we can use a boolean expression
- //or compare it with a default constructed iterator
- assert(!beg_it == (beg_it == multiallocation_iterator()));
-
- //Check if the memory allocation was successful
- if(!beg_it) return 1;
-
- //Allocated buffers
- std::vector<char*> allocated_buffers;
-
- //Initialize our data
- for( multiallocation_iterator it = beg_it, end_it; it != end_it; ){
- allocated_buffers.push_back(&*it);
- //The iterator must be incremented before overwriting memory
- //because otherwise, the iterator is invalidated.
- std::memset(&*it++, 0, 100);
- }
-
- //Now deallocate
- while(!allocated_buffers.empty()){
- managed_shm.deallocate(allocated_buffers.back());
- allocated_buffers.pop_back();
- }
-
- //Allocate 10 buffers of different sizes in a single call. Throwing version
- std::size_t sizes[10];
- for(std::size_t i = 0; i < 10; ++i)
- sizes[i] = i*3;
-
- beg_it = managed_shm.allocate_many(sizes, 10);
-
- //Iterate each allocated buffer and deallocate
- //The "end" condition can be also checked with operator!
- for(multiallocation_iterator it = beg_it; it;){
- //The iterator must be incremented before overwriting memory
- //because otherwise, the iterator is invalidated.
- managed_shm.deallocate(&*it++);
- }
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ managed_shared_memory managed_shm(create_only, "MySharedMemory", 65536);
+
+ //Allocate 16 elements of 100 bytes in a single call. Non-throwing version.
+ multiallocation_chain chain(managed_shm.allocate_many(100, 16, std::nothrow));
+
+ //Check if the memory allocation was successful
+ if(chain.empty()) return 1;
+
+ //Allocated buffers
+ std::vector<void*> allocated_buffers;
+
+ //Initialize our data
+ while(!chain.empty()){
+ void *buf = chain.front();
+ chain.pop_front();
+ allocated_buffers.push_back(buf);
+ //The iterator must be incremented before overwriting memory
+ //because otherwise, the iterator is invalidated.
+ std::memset(buf, 0, 100);
}
- catch(...){
- shared_memory_object::remove("MyManagedShm");
- throw;
+
+ //Now deallocate
+ while(!allocated_buffers.empty()){
+ managed_shm.deallocate(allocated_buffers.back());
+ allocated_buffers.pop_back();
}
- shared_memory_object::remove("MyManagedShm");
+
+ //Allocate 10 buffers of different sizes in a single call. Throwing version
+ std::size_t sizes[10];
+ for(std::size_t i = 0; i < 10; ++i)
+ sizes[i] = i*3;
+
+ chain = managed_shm.allocate_many(sizes, 10);
+ managed_shm.deallocate_many(boost::interprocess::move(chain));
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_managed_raw_allocation.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_managed_raw_allocation.cpp (original)
+++ trunk/libs/interprocess/example/doc_managed_raw_allocation.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -15,29 +15,28 @@
{
using namespace boost::interprocess;
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
//Managed memory segment that allocates portions of a shared memory
//segment with the default management algorithm
- shared_memory_object::remove("MyManagedShm");
- try{
- managed_shared_memory managed_shm(create_only, "MyManagedShm", 65536);
-
- //Allocate 100 bytes of memory from segment, throwing version
- void *ptr = managed_shm.allocate(100);
-
- //Deallocate it
- managed_shm.deallocate(ptr);
-
- //Non throwing version
- ptr = managed_shm.allocate(100, std::nothrow);
-
- //Deallocate it
- managed_shm.deallocate(ptr);
- }
- catch(...){
- shared_memory_object::remove("MyManagedShm");
- throw;
- }
- shared_memory_object::remove("MyManagedShm");
+ managed_shared_memory managed_shm(create_only, "MySharedMemory", 65536);
+
+ //Allocate 100 bytes of memory from segment, throwing version
+ void *ptr = managed_shm.allocate(100);
+
+ //Deallocate it
+ managed_shm.deallocate(ptr);
+
+ //Non throwing version
+ ptr = managed_shm.allocate(100, std::nothrow);
+
+ //Deallocate it
+ managed_shm.deallocate(ptr);
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_map.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_map.cpp (original)
+++ trunk/libs/interprocess/example/doc_map.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,56 +19,55 @@
int main ()
{
using namespace boost::interprocess;
+
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
//Shared memory front-end that is able to construct objects
//associated with a c-string. Erase previous shared memory with the name
//to be used and create the memory segment at the specified address and initialize resources
- shared_memory_object::remove("MySharedMemory");
-
- try{
- managed_shared_memory segment
- (create_only
- ,"MySharedMemory" //segment name
- ,65536); //segment size in bytes
-
- //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
- //so the allocator must allocate that pair.
- typedef int KeyType;
- typedef float MappedType;
- typedef std::pair<const int, float> ValueType;
-
- //Alias an STL compatible allocator of for the map.
- //This allocator will allow to place containers
- //in managed shared memory segments
- typedef allocator<ValueType, managed_shared_memory::segment_manager>
- ShmemAllocator;
-
- //Alias a map of ints that uses the previous STL-like allocator.
- //Note that the third parameter argument is the ordering function
- //of the map, just like with std::map, used to compare the keys.
- typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;
-
- //Initialize the shared memory STL-compatible allocator
- ShmemAllocator alloc_inst (segment.get_segment_manager());
-
- //Construct a shared memory map.
- //Note that the first parameter is the comparison function,
- //and the second one the allocator.
- //This the same signature as std::map's constructor taking an allocator
- MyMap *mymap =
- segment.construct<MyMap>("MyMap") //object name
- (std::less<int>() //first ctor parameter
- ,alloc_inst); //second ctor parameter
-
- //Insert data in the map
- for(int i = 0; i < 100; ++i){
- mymap->insert(std::pair<const int, float>(i, (float)i));
- }
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
+ managed_shared_memory segment
+ (create_only
+ ,"MySharedMemory" //segment name
+ ,65536); //segment size in bytes
+
+ //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
+ //so the allocator must allocate that pair.
+ typedef int KeyType;
+ typedef float MappedType;
+ typedef std::pair<const int, float> ValueType;
+
+ //Alias an STL compatible allocator of for the map.
+ //This allocator will allow to place containers
+ //in managed shared memory segments
+ typedef allocator<ValueType, managed_shared_memory::segment_manager>
+ ShmemAllocator;
+
+ //Alias a map of ints that uses the previous STL-like allocator.
+ //Note that the third parameter argument is the ordering function
+ //of the map, just like with std::map, used to compare the keys.
+ typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;
+
+ //Initialize the shared memory STL-compatible allocator
+ ShmemAllocator alloc_inst (segment.get_segment_manager());
+
+ //Construct a shared memory map.
+ //Note that the first parameter is the comparison function,
+ //and the second one the allocator.
+ //This the same signature as std::map's constructor taking an allocator
+ MyMap *mymap =
+ segment.construct<MyMap>("MyMap") //object name
+ (std::less<int>() //first ctor parameter
+ ,alloc_inst); //second ctor parameter
+
+ //Insert data in the map
+ for(int i = 0; i < 100; ++i){
+ mymap->insert(std::pair<const int, float>(i, (float)i));
}
- shared_memory_object::remove("MySharedMemory");
return 0;
}
//]
Deleted: trunk/libs/interprocess/example/doc_message_queueA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_message_queueA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,45 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_message_queueA
-#include <boost/interprocess/ipc/message_queue.hpp>
-#include <iostream>
-#include <vector>
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Erase previous message queue
- message_queue::remove("message_queue");
-
- //Create a message_queue.
- message_queue mq
- (create_only //only create
- ,"message_queue" //name
- ,100 //max message number
- ,sizeof(int) //max message size
- );
-
- //Send 100 numbers
- for(int i = 0; i < 100; ++i){
- mq.send(&i, sizeof(i), 0);
- }
- }
- catch(interprocess_exception &ex){
- std::cout << ex.what() << std::endl;
- return 1;
- }
-
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_message_queueB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_message_queueB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,47 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_message_queueB
-#include <boost/interprocess/ipc/message_queue.hpp>
-#include <iostream>
-#include <vector>
-
-using namespace boost::interprocess;
-
-int main ()
-{
- try{
- //Open a message queue.
- message_queue mq
- (open_only //only create
- ,"message_queue" //name
- );
-
- unsigned int priority;
- std::size_t recvd_size;
-
- //Receive 100 numbers
- for(int i = 0; i < 100; ++i){
- int number;
- mq.receive(&number, sizeof(number), recvd_size, priority);
- if(number != i || recvd_size != sizeof(number))
- return 1;
- }
- }
- catch(interprocess_exception &ex){
- message_queue::remove("message_queue");
- std::cout << ex.what() << std::endl;
- return 1;
- }
- message_queue::remove("message_queue");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_move_containers.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_move_containers.cpp (original)
+++ trunk/libs/interprocess/example/doc_move_containers.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -28,58 +28,57 @@
typedef allocator<MyShmString, SegmentManager> StringAllocator;
typedef vector<MyShmString, StringAllocator> MyShmStringVector;
- //Remove old shared memory and create new one
- shared_memory_object::remove("myshm");
- try{
- managed_shared_memory shm(create_only, "myshm", 10000);
-
- //Create allocators
- CharAllocator charallocator (shm.get_segment_manager());
- StringAllocator stringallocator(shm.get_segment_manager());
-
- //Create a vector of strings in shared memory.
- MyShmStringVector *myshmvector =
- shm.construct<MyShmStringVector>("myshmvector")(stringallocator);
-
- //Insert 50 strings in shared memory. The strings will be allocated
- //only once and no string copy-constructor will be called when inserting
- //strings, leading to a great performance.
- MyShmString string_to_compare(charallocator);
- string_to_compare = "this is a long, long, long, long, long, long, string...";
-
- myshmvector->reserve(50);
- for(int i = 0; i < 50; ++i){
- MyShmString move_me(string_to_compare);
- //In the following line, no string copy-constructor will be called.
- //"move_me"'s contents will be transferred to the string created in
- //the vector
- myshmvector->push_back(boost::interprocess::move(move_me));
-
- //The source string is in default constructed state
- assert(move_me.empty());
-
- //The newly created string will be equal to the "move_me"'s old contents
- assert(myshmvector->back() == string_to_compare);
- }
-
- //Now erase a string...
- myshmvector->pop_back();
-
- //...And insert one in the first position.
- //No string copy-constructor or assignments will be called, but
- //move constructors and move-assignments. No memory allocation
- //function will be called in this operations!!
- myshmvector->insert(myshmvector->begin(), boost::interprocess::move(string_to_compare));
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ managed_shared_memory shm(create_only, "MySharedMemory", 10000);
+
+ //Create allocators
+ CharAllocator charallocator (shm.get_segment_manager());
+ StringAllocator stringallocator(shm.get_segment_manager());
+
+ //Create a vector of strings in shared memory.
+ MyShmStringVector *myshmvector =
+ shm.construct<MyShmStringVector>("myshmvector")(stringallocator);
+
+ //Insert 50 strings in shared memory. The strings will be allocated
+ //only once and no string copy-constructor will be called when inserting
+ //strings, leading to a great performance.
+ MyShmString string_to_compare(charallocator);
+ string_to_compare = "this is a long, long, long, long, long, long, string...";
+
+ myshmvector->reserve(50);
+ for(int i = 0; i < 50; ++i){
+ MyShmString move_me(string_to_compare);
+ //In the following line, no string copy-constructor will be called.
+ //"move_me"'s contents will be transferred to the string created in
+ //the vector
+ myshmvector->push_back(boost::interprocess::move(move_me));
- //Destroy vector. This will free all strings that the vector contains
- shm.destroy_ptr(myshmvector);
- }
- catch(...){
- shared_memory_object::remove("myshmvector");
- throw;
+ //The source string is in default constructed state
+ assert(move_me.empty());
+
+ //The newly created string will be equal to the "move_me"'s old contents
+ assert(myshmvector->back() == string_to_compare);
}
- shared_memory_object::remove("myshmvector");
+
+ //Now erase a string...
+ myshmvector->pop_back();
+
+ //...And insert one in the first position.
+ //No string copy-constructor or assignments will be called, but
+ //move constructors and move-assignments. No memory allocation
+ //function will be called in this operations!!
+ myshmvector->insert(myshmvector->begin(), boost::interprocess::move(string_to_compare));
+
+ //Destroy vector. This will free all strings that the vector contains
+ shm.destroy_ptr(myshmvector);
return 0;
}
//]
#include <boost/interprocess/detail/config_end.hpp>
+
Modified: trunk/libs/interprocess/example/doc_multi_index.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_multi_index.cpp (original)
+++ trunk/libs/interprocess/example/doc_multi_index.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -61,30 +61,27 @@
int main ()
{
- //Erase previous shared memory with the name
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,"MySharedMemory", 65536);
+ //Create shared memory
+ managed_shared_memory segment(create_only,"MySharedMemory", 65536);
- //Construct the multi_index in shared memory
- employee_set *es = segment.construct<employee_set>
- ("My MultiIndex Container") //Container's name in shared memory
- ( employee_set::ctor_args_list()
- , segment.get_allocator<employee>()); //Ctor parameters
+ //Construct the multi_index in shared memory
+ employee_set *es = segment.construct<employee_set>
+ ("My MultiIndex Container") //Container's name in shared memory
+ ( employee_set::ctor_args_list()
+ , segment.get_allocator<employee>()); //Ctor parameters
- //Now insert elements
- char_allocator ca(segment.get_allocator<char>());
- es->insert(employee(0,31, "Joe", ca));
- es->insert(employee(1,27, "Robert", ca));
- es->insert(employee(2,40, "John", ca));
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //Now insert elements
+ char_allocator ca(segment.get_allocator<char>());
+ es->insert(employee(0,31, "Joe", ca));
+ es->insert(employee(1,27, "Robert", ca));
+ es->insert(employee(2,40, "John", ca));
return 0;
}
//]
Added: trunk/libs/interprocess/example/doc_named_alloc.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/doc_named_alloc.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,103 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+//[doc_named_alloc
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <cstdlib> //std::system
+#include <cstddef>
+#include <cassert>
+#include <utility>
+
+int main(int argc, char *argv[])
+{
+ using namespace boost::interprocess;
+ typedef std::pair<double, int> MyType;
+
+ if(argc == 1){ //Parent process
+ //Remove shared memory on construction and destruction
+ struct shm_remove
+ {
+ shm_remove() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Construct managed shared memory
+ managed_shared_memory segment(create_only, "MySharedMemory", 65536);
+
+ //Create an object of MyType initialized to {0.0, 0}
+ MyType *instance = segment.construct<MyType>
+ ("MyType instance") //name of the object
+ (0.0, 0); //ctor first argument
+
+ //Create an array of 10 elements of MyType initialized to {0.0, 0}
+ MyType *array = segment.construct<MyType>
+ ("MyType array") //name of the object
+ [10] //number of elements
+ (0.0, 0); //Same two ctor arguments for all objects
+
+ //Create an array of 3 elements of MyType initializing each one
+ //to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...
+ float float_initializer[3] = { 0.0, 1.0, 2.0 };
+ int int_initializer[3] = { 0, 1, 2 };
+
+ MyType *array_it = segment.construct_it<MyType>
+ ("MyType array from it") //name of the object
+ [3] //number of elements
+ ( &float_initializer[0] //Iterator for the 1st ctor argument
+ , &int_initializer[0]); //Iterator for the 2nd ctor argument
+
+ //Launch child process
+ std::string s(argv[0]); s += " child";
+ if(0 != std::system(s.c_str()))
+ return 1;
+
+ //<-
+ (void)instance;
+ (void)array;
+ (void)array_it;
+ //->
+
+ //Check child has destroyed all objects
+ if(segment.find<MyType>("MyType array").first ||
+ segment.find<MyType>("MyType instance").first ||
+ segment.find<MyType>("MyType array from it").first)
+ return 1;
+ }
+ else{
+ //Open managed shared memory
+ managed_shared_memory segment(open_only, "MySharedMemory");
+
+ std::pair<MyType*, std::size_t> res;
+
+ //Find the array
+ res = segment.find<MyType> ("MyType array");
+ //Length should be 10
+ if(res.second != 10) return 1;
+
+ //Find the object
+ res = segment.find<MyType> ("MyType instance");
+ //Length should be 1
+ if(res.second != 1) return 1;
+
+ //Find the array constructed from iterators
+ res = segment.find<MyType> ("MyType array from it");
+ //Length should be 3
+ if(res.second != 3) return 1;
+
+ //We're done, delete all the objects
+ segment.destroy<MyType>("MyType array");
+ segment.destroy<MyType>("MyType instance");
+ segment.destroy<MyType>("MyType array from it");
+ }
+ return 0;
+}
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_named_allocA.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_named_allocA.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,61 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-//[doc_named_allocA
-#include <boost/interprocess/managed_shared_memory.hpp>
-#include <utility>
-
-int main ()
-{
- using namespace boost::interprocess;
- typedef std::pair<double, int> MyType;
-
- try{
- //A special shared memory where we can
- //construct objects associated with a name.
- //First remove any old shared memory of the same name, create
- //the shared memory segment and initialize needed resources
- shared_memory_object::remove("MySharedMemory");
- managed_shared_memory segment
- //create segment name segment size
- (create_only, "MySharedMemory", 65536);
-
- //Create an object of MyType initialized to {0.0, 0}
- MyType *instance = segment.construct<MyType>
- ("MyType instance") //name of the object
- (0.0, 0); //ctor first argument
-
- //Create an array of 10 elements of MyType initialized to {0.0, 0}
- MyType *array = segment.construct<MyType>
- ("MyType array") //name of the object
- [10] //number of elements
- (0.0, 0); //Same two ctor arguments for all objects
-
- //Create an array of 3 elements of MyType initializing each one
- //to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...
- float float_initializer[3] = { 0.0, 1.0, 2.0 };
- int int_initializer[3] = { 0, 1, 2 };
-
- MyType *array_it = segment.construct_it<MyType>
- ("MyType array from it") //name of the object
- [3] //number of elements
- ( &float_initializer[0] //Iterator for the 1st ctor argument
- , &int_initializer[0]); //Iterator for the 2nd ctor argument
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_named_allocB.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_named_allocB.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,63 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-//[doc_named_allocB
-#include <boost/interprocess/managed_shared_memory.hpp>
-#include <cstddef>
-#include <utility>
-#include <cassert>
-
-int main ()
-{
- using namespace boost::interprocess;
- typedef std::pair<double, int> MyType;
-
- try{
- //A special shared memory where we can
- //construct objects associated with a name.
- //Connect to the already created shared memory segment
- //and initialize needed resources
- managed_shared_memory segment(open_only, "MySharedMemory");
-
- std::pair<MyType*, std::size_t> res;
-
- //Find the array
- res = segment.find<MyType> ("MyType array");
- //Length should be 10
- assert(res.second == 10);
-
- //Find the object
- res = segment.find<MyType> ("MyType instance");
- //Length should be 1
- assert(res.second == 1);
-
- //Find the array constructed from iterators
- res = segment.find<MyType> ("MyType array from it");
- //Length should be 3
- assert(res.second == 3);
-
- //Use data
- // . . .
-
- //We're done, delete all the objects
- segment.destroy<MyType>("MyType array");
- segment.destroy<MyType>("MyType instance");
- segment.destroy<MyType>("MyType array from it");
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
- return 0;
-}
-//]
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_named_mutex.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_named_mutex.cpp (original)
+++ trunk/libs/interprocess/example/doc_named_mutex.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -13,6 +13,7 @@
#include <boost/interprocess/sync/named_mutex.hpp>
#include <fstream>
#include <iostream>
+#include <cstdio>
int main ()
{
@@ -37,10 +38,12 @@
}
catch(interprocess_exception &ex){
named_mutex::remove("fstream_named_mutex");
+ std::remove("file_name");
std::cout << ex.what() << std::endl;
return 1;
}
named_mutex::remove("fstream_named_mutex");
+ std::remove("file_name");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_node_allocator.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_node_allocator.cpp (original)
+++ trunk/libs/interprocess/example/doc_node_allocator.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,46 +18,44 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Create a node_allocator that allocates ints from the managed segment
+ //The number of chunks per segment is the default value
+ typedef node_allocator<int, managed_shared_memory::segment_manager>
+ node_allocator_t;
+ node_allocator_t allocator_instance(segment.get_segment_manager());
+
+ //Create another node_allocator. Since the segment manager address
+ //is the same, this node_allocator will be
+ //attached to the same pool so "allocator_instance2" can deallocate
+ //nodes allocated by "allocator_instance"
+ node_allocator_t allocator_instance2(segment.get_segment_manager());
+
+ //Create another node_allocator using copy-constructor. This
+ //node_allocator will also be attached to the same pool
+ node_allocator_t allocator_instance3(allocator_instance2);
+
+ //All allocators are equal
+ assert(allocator_instance == allocator_instance2);
+ assert(allocator_instance2 == allocator_instance3);
+
+ //So memory allocated with one can be deallocated with another
+ allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
+ allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Create a node_allocator that allocates ints from the managed segment
- //The number of chunks per segment is the default value
- typedef node_allocator<int, managed_shared_memory::segment_manager>
- node_allocator_t;
- node_allocator_t allocator_instance(segment.get_segment_manager());
-
- //Create another node_allocator. Since the segment manager address
- //is the same, this node_allocator will be
- //attached to the same pool so "allocator_instance2" can deallocate
- //nodes allocated by "allocator_instance"
- node_allocator_t allocator_instance2(segment.get_segment_manager());
-
- //Create another node_allocator using copy-constructor. This
- //node_allocator will also be attached to the same pool
- node_allocator_t allocator_instance3(allocator_instance2);
-
- //All allocators are equal
- assert(allocator_instance == allocator_instance2);
- assert(allocator_instance2 == allocator_instance3);
-
- //So memory allocated with one can be deallocated with another
- allocator_instance2.deallocate(allocator_instance.allocate(1), 1);
- allocator_instance3.deallocate(allocator_instance2.allocate(1), 1);
-
- //The common pool will be destroyed here, since no allocator is
- //attached to the pool
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //The common pool will be destroyed here, since no allocator is
+ //attached to the pool
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_offset_ptr.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_offset_ptr.cpp (original)
+++ trunk/libs/interprocess/example/doc_offset_ptr.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -24,45 +24,41 @@
int main ()
{
- //Destroy any previous shared memory with the name to be used.
- //Create a special shared memory from which we can
- //allocate buffers of raw memory.
- shared_memory_object::remove("MySharedMemory");
- try{
- managed_shared_memory segment(
- create_only,
- "MySharedMemory", //segment name
- 65536); //segment size in bytes
-
- //Create linked list with 10 nodes in shared memory
- offset_ptr<list_node> prev = 0, current, first;
-
- int i;
- for(i = 0; i < 10; ++i, prev = current){
- current = static_cast<list_node*>(segment.allocate(sizeof(list_node)));
- current->value = i;
- current->next = 0;
-
- if(!prev)
- first = current;
- else
- prev->next = current;
- }
-
- //Communicate list to other processes
- //. . .
- //When done, destroy list
- for(current = first; current; /**/){
- prev = current;
- current = current->next;
- segment.deallocate(prev.get());
- }
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ managed_shared_memory segment(
+ create_only,
+ "MySharedMemory", //segment name
+ 65536); //segment size in bytes
+
+ //Create linked list with 10 nodes in shared memory
+ offset_ptr<list_node> prev = 0, current, first;
+
+ int i;
+ for(i = 0; i < 10; ++i, prev = current){
+ current = static_cast<list_node*>(segment.allocate(sizeof(list_node)));
+ current->value = i;
+ current->next = 0;
+
+ if(!prev)
+ first = current;
+ else
+ prev->next = current;
}
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
+
+ //Communicate list to other processes
+ //. . .
+ //When done, destroy list
+ for(current = first; current; /**/){
+ prev = current;
+ current = current->next;
+ segment.deallocate(prev.get());
}
- shared_memory_object::remove("MySharedMemory");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_private_adaptive_pool.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_private_adaptive_pool.cpp (original)
+++ trunk/libs/interprocess/example/doc_private_adaptive_pool.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,42 +18,40 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Create a private_adaptive_pool that allocates ints from the managed segment
+ //The number of chunks per segment is the default value
+ typedef private_adaptive_pool<int, managed_shared_memory::segment_manager>
+ private_adaptive_pool_t;
+ private_adaptive_pool_t allocator_instance(segment.get_segment_manager());
+
+ //Create another private_adaptive_pool.
+ private_adaptive_pool_t allocator_instance2(segment.get_segment_manager());
+
+ //Although the segment manager address
+ //is the same, this private_adaptive_pool will have its own pool so
+ //"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance".
+ //"allocator_instance2" is NOT equal to "allocator_instance"
+ assert(allocator_instance != allocator_instance2);
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Create a private_adaptive_pool that allocates ints from the managed segment
- //The number of chunks per segment is the default value
- typedef private_adaptive_pool<int, managed_shared_memory::segment_manager>
- private_adaptive_pool_t;
- private_adaptive_pool_t allocator_instance(segment.get_segment_manager());
-
- //Create another private_adaptive_pool.
- private_adaptive_pool_t allocator_instance2(segment.get_segment_manager());
-
- //Although the segment manager address
- //is the same, this private_adaptive_pool will have its own pool so
- //"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance".
- //"allocator_instance2" is NOT equal to "allocator_instance"
- assert(allocator_instance != allocator_instance2);
-
- //Create another adaptive_pool using copy-constructor.
- private_adaptive_pool_t allocator_instance3(allocator_instance2);
-
- //This allocator is also unequal to allocator_instance2
- assert(allocator_instance2 != allocator_instance3);
-
- //Pools are destroyed with the allocators
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //Create another adaptive_pool using copy-constructor.
+ private_adaptive_pool_t allocator_instance3(allocator_instance2);
+
+ //This allocator is also unequal to allocator_instance2
+ assert(allocator_instance2 != allocator_instance3);
+
+ //Pools are destroyed with the allocators
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_private_node_allocator.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_private_node_allocator.cpp (original)
+++ trunk/libs/interprocess/example/doc_private_node_allocator.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,42 +18,40 @@
int main ()
{
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only,
+ "MySharedMemory", //segment name
+ 65536);
+
+ //Create a private_node_allocator that allocates ints from the managed segment
+ //The number of chunks per segment is the default value
+ typedef private_node_allocator<int, managed_shared_memory::segment_manager>
+ private_node_allocator_t;
+ private_node_allocator_t allocator_instance(segment.get_segment_manager());
+
+ //Create another private_node_allocator.
+ private_node_allocator_t allocator_instance2(segment.get_segment_manager());
+
+ //Although the segment manager address
+ //is the same, this private_node_allocator will have its own pool so
+ //"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance".
+ //"allocator_instance2" is NOT equal to "allocator_instance"
+ assert(allocator_instance != allocator_instance2);
- try{
- //Create shared memory
- managed_shared_memory segment(create_only,
- "MySharedMemory", //segment name
- 65536);
-
- //Create a private_node_allocator that allocates ints from the managed segment
- //The number of chunks per segment is the default value
- typedef private_node_allocator<int, managed_shared_memory::segment_manager>
- private_node_allocator_t;
- private_node_allocator_t allocator_instance(segment.get_segment_manager());
-
- //Create another private_node_allocator.
- private_node_allocator_t allocator_instance2(segment.get_segment_manager());
-
- //Although the segment manager address
- //is the same, this private_node_allocator will have its own pool so
- //"allocator_instance2" CAN'T deallocate nodes allocated by "allocator_instance".
- //"allocator_instance2" is NOT equal to "allocator_instance"
- assert(allocator_instance != allocator_instance2);
-
- //Create another node_allocator using copy-constructor.
- private_node_allocator_t allocator_instance3(allocator_instance2);
-
- //This allocator is also unequal to allocator_instance2
- assert(allocator_instance2 != allocator_instance3);
-
- //Pools are destroyed with the allocators
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
- }
- shared_memory_object::remove("MySharedMemory");
+ //Create another node_allocator using copy-constructor.
+ private_node_allocator_t allocator_instance3(allocator_instance2);
+
+ //This allocator is also unequal to allocator_instance2
+ assert(allocator_instance2 != allocator_instance3);
+
+ //Pools are destroyed with the allocators
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_scoped_ptr.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_scoped_ptr.cpp (original)
+++ trunk/libs/interprocess/example/doc_scoped_ptr.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -47,60 +47,59 @@
int main ()
{
//Create shared memory
- shared_memory_object::remove("my_shmem");
- try{
- managed_shared_memory shmem(create_only, "my_shmem", 10000);
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
- //In the first try, there will be no exceptions
- //in the second try we will throw an exception
- for(int i = 0; i < 2; ++i){
- //Create an object in shared memory
- my_class * my_object = shmem.construct<my_class>("my_object")();
- my_class * my_object2 = shmem.construct<my_class>(anonymous_instance)();
- shmem.destroy_ptr(my_object2);
-
- //Since the next shared memory allocation can throw
- //assign it to a scoped_ptr so that if an exception occurs
- //we destroy the object automatically
- my_deleter<my_class> d(shmem.get_segment_manager());
+ managed_shared_memory shmem(create_only, "MySharedMemory", 10000);
- try{
- scoped_ptr<my_class, my_deleter<my_class> > s_ptr(my_object, d);
- //Let's emulate a exception capable operation
- //In the second try, throw an exception
- if(i == 1){
- throw(my_exception());
- }
- //If we have passed the dangerous zone
- //we can release the scoped pointer
- //to avoid destruction
- s_ptr.release();
+ //In the first try, there will be no exceptions
+ //in the second try we will throw an exception
+ for(int i = 0; i < 2; ++i){
+ //Create an object in shared memory
+ my_class * my_object = shmem.construct<my_class>("my_object")();
+ my_class * my_object2 = shmem.construct<my_class>(anonymous_instance)();
+ shmem.destroy_ptr(my_object2);
+
+ //Since the next shared memory allocation can throw
+ //assign it to a scoped_ptr so that if an exception occurs
+ //we destroy the object automatically
+ my_deleter<my_class> d(shmem.get_segment_manager());
+
+ try{
+ scoped_ptr<my_class, my_deleter<my_class> > s_ptr(my_object, d);
+ //Let's emulate a exception capable operation
+ //In the second try, throw an exception
+ if(i == 1){
+ throw(my_exception());
}
- catch(const my_exception &){}
- //Here, scoped_ptr is destroyed
- //so it we haven't thrown an exception
- //the object should be there, otherwise, destroyed
- if(i == 0){
- //Make sure the object is alive
- if(!shmem.find<my_class>("my_object").first){
- return 1;
- }
- //Now we can use it and delete it manually
- shmem.destroy<my_class>("my_object");
+ //If we have passed the dangerous zone
+ //we can release the scoped pointer
+ //to avoid destruction
+ s_ptr.release();
+ }
+ catch(const my_exception &){}
+ //Here, scoped_ptr is destroyed
+ //so it we haven't thrown an exception
+ //the object should be there, otherwise, destroyed
+ if(i == 0){
+ //Make sure the object is alive
+ if(!shmem.find<my_class>("my_object").first){
+ return 1;
}
- else{
- //Make sure the object has been deleted
- if(shmem.find<my_class>("my_object").first){
- return 1;
- }
+ //Now we can use it and delete it manually
+ shmem.destroy<my_class>("my_object");
+ }
+ else{
+ //Make sure the object has been deleted
+ if(shmem.find<my_class>("my_object").first){
+ return 1;
}
}
}
- catch(...){
- shared_memory_object::remove("my_shmem");
- throw;
- }
- shared_memory_object::remove("my_shmem");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_shared_memory.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_shared_memory.cpp (original)
+++ trunk/libs/interprocess/example/doc_shared_memory.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -11,18 +11,24 @@
//[doc_shared_memory
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
#include <cstring>
+#include <cstdlib>
+#include <string>
-int main ()
+int main(int argc, char *argv[])
{
using namespace boost::interprocess;
- try{
- //Erase previous shared memory
- shared_memory_object::remove("shared_memory");
+
+ if(argc == 1){ //Parent process
+ //Remove shared memory on construction and destruction
+ struct shm_remove
+ {
+ shm_remove() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
//Create a shared memory object.
- shared_memory_object shm (create_only, "shared_memory", read_write);
+ shared_memory_object shm (create_only, "MySharedMemory", read_write);
//Set size
shm.truncate(1000);
@@ -32,11 +38,24 @@
//Write all the memory to 1
std::memset(region.get_address(), 1, region.get_size());
+
+ //Launch child process
+ std::string s(argv[0]); s += " child";
+ if(0 != std::system(s.c_str()))
+ return 1;
}
- catch(interprocess_exception &ex){
- shared_memory_object::remove("shared_memory");
- std::cout << ex.what() << std::endl;
- return 1;
+ else{
+ //Open already created shared memory object.
+ shared_memory_object shm (open_only, "MySharedMemory", read_only);
+
+ //Map the whole shared memory in this process
+ mapped_region region(shm, read_only);
+
+ //Check that memory was initialized to 1
+ char *mem = static_cast<char*>(region.get_address());
+ for(std::size_t i = 0; i < region.get_size(); ++i)
+ if(*mem++ != 1)
+ return 1; //Error checking memory
}
return 0;
}
Deleted: trunk/libs/interprocess/example/doc_shared_memory2.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_shared_memory2.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,48 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-//[doc_shared_memory2
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
-#include <cstring>
-
-int main ()
-{
- using namespace boost::interprocess;
- shared_memory_object::remove("shared_memory");
- try{
- //Open already created shared memory object.
- shared_memory_object shm (open_only, "shared_memory", read_only);
-
- //Map the whole shared memory in this process
- mapped_region region(shm, read_only);
-
- //Check that memory was initialized to 1
- const char *mem = static_cast<char*>(region.get_address());
- for(std::size_t i = 0; i < region.get_size(); ++i){
- if(*mem++ != 1){
- std::cout << "Error checking memory!" << std::endl;
- return 1;
- }
- }
- std::cout << "Test successful!" << std::endl;
- }
- catch(interprocess_exception &ex){
- std::cout << "Unexpected exception: " << ex.what() << std::endl;
- shared_memory_object::remove("shared_memory");
- return 1;
- }
- shared_memory_object::remove("shared_memory");
- return 0;
-}
-//]
-
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_shared_ptr.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_shared_ptr.cpp (original)
+++ trunk/libs/interprocess/example/doc_shared_ptr.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -16,7 +16,6 @@
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
#include <boost/interprocess/smart_ptr/weak_ptr.hpp>
#include <cassert>
-#include <cstdio> //std::remove
using namespace boost::interprocess;
@@ -47,7 +46,7 @@
int main ()
{
//Destroy any previous file with the name to be used.
- std::remove("MyMappedFile");
+ file_mapping::remove("MyMappedFile");
{
managed_mapped_file file(create_only, "MyMappedFile", 4096);
@@ -114,7 +113,7 @@
//The reference count will be deallocated when all weak pointers
//disappear. After that, the file is unmapped.
}
- std::remove("MyMappedFile");
+ file_mapping::remove("MyMappedFile");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_shared_ptr_explicit.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_shared_ptr_explicit.cpp (original)
+++ trunk/libs/interprocess/example/doc_shared_ptr_explicit.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -31,8 +31,13 @@
int main ()
{
- //Destroy any previous segment with the name to be used.
- shared_memory_object::remove("MySharedMemory");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
managed_shared_memory segment(create_only, "MySharedMemory", 4096);
//Create a shared pointer in shared memory
@@ -49,7 +54,6 @@
//Destroy "shared ptr". "object to share" will be automatically destroyed
segment.destroy_ptr(&shared_ptr_instance);
- shared_memory_object::remove("MySharedMemory");
return 0;
}
//]
Added: trunk/libs/interprocess/example/doc_spawn_vector.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/example/doc_spawn_vector.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,79 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+//[run_doc_spawn_vector
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <string>
+#include <cstdlib> //std::system
+
+using namespace boost::interprocess;
+
+//Define an STL compatible allocator of ints that allocates from the managed_shared_memory.
+//This allocator will allow placing containers in the segment
+typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
+
+//Alias a vector that uses the previous STL-like allocator so that allocates
+//its values from the segment
+typedef vector<int, ShmemAllocator> MyVector;
+
+//Main function. For parent process argc == 1, for child process argc == 2
+int main(int argc, char *argv[])
+{
+ if(argc == 1){ //Parent process
+ //Remove shared memory on construction and destruction
+ struct shm_remove
+ {
+ shm_remove() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a new segment with given name and size
+ managed_shared_memory segment(create_only ,"MySharedMemory", 65536);
+
+ //Initialize shared memory STL-compatible allocator
+ const ShmemAllocator alloc_inst (segment.get_segment_manager());
+
+ //Construct a vector named "MyVector" in shared memory with argument alloc_inst
+ MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);
+
+ for(int i = 0; i < 100; ++i) //Insert data in the vector
+ myvector->push_back(i);
+
+ //Launch child process
+ std::string s(argv[0]); s += " child";
+ if(0 != std::system(s.c_str()))
+ return 1;
+
+ //Check child has destroyed the vector
+ if(segment.find<MyVector>("MyVector").first)
+ return 1;
+ }
+ else{ //Child process
+ //Open the managed segment
+ managed_shared_memory segment(open_only, "MySharedMemory");
+
+ //Find the vector using the c-string name
+ MyVector *myvector = segment.find<MyVector>("MyVector").first;
+
+ //Use vector in reverse order
+ std::sort(myvector->rbegin(), myvector->rend());
+
+ //When done, destroy the vector from the segment
+ segment.destroy<MyVector>("MyVector");
+ }
+
+ return 0;
+};
+
+//]
+#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/example/doc_unique_ptr.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_unique_ptr.cpp (original)
+++ trunk/libs/interprocess/example/doc_unique_ptr.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,7 +18,6 @@
#include <boost/interprocess/containers/list.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <cassert>
-#include <cstdio> //std::remove
using namespace boost::interprocess;
@@ -49,7 +48,7 @@
int main ()
{
//Destroy any previous file with the name to be used.
- std::remove("MyMappedFile");
+ file_mapping::remove("MyMappedFile");
{
managed_mapped_file file(create_only, "MyMappedFile", 65536);
@@ -72,9 +71,8 @@
//Now insert all values
for(int i = 0; i < 100; ++i){
- unique_vector->push_back(
- make_managed_unique_ptr(file.construct<MyType>(anonymous_instance)(i), file)
- );
+ unique_ptr_type p(make_managed_unique_ptr(file.construct<MyType>(anonymous_instance)(i), file));
+ unique_vector->push_back(boost::interprocess::move(p));
assert(unique_vector->back()->number_ == i);
}
@@ -84,7 +82,7 @@
//Pass ownership of all values to the list
for(int i = 99; !unique_vector->empty(); --i){
- unique_list->push_front(move(unique_vector->back()));
+ unique_list->push_front(boost::interprocess::move(unique_vector->back()));
//The unique ptr of the vector is now empty...
assert(unique_vector->back() == 0);
unique_vector->pop_back();
@@ -114,7 +112,7 @@
//Now destroy the list. All elements will be automatically deallocated.
file.destroy_ptr(unique_list);
}
- std::remove("MyMappedFile");
+ file_mapping::remove("MyMappedFile");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_unordered_map.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_unordered_map.cpp (original)
+++ trunk/libs/interprocess/example/doc_unordered_map.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -20,46 +20,43 @@
int main ()
{
using namespace boost::interprocess;
- //Erase previous shared memory with the name
- shared_memory_object::remove("MySharedMemory");
-
- try{
- //Create shared memory
- managed_shared_memory segment(create_only ,"MySharedMemory" ,65536);
-
- //Note that unordered_map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
- //so the allocator must allocate that pair.
- typedef int KeyType;
- typedef float MappedType;
- typedef std::pair<const int, float> ValueType;
-
- //Typedef the allocator
- typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;
-
- //Alias an unordered_map of ints that uses the previous STL-like allocator.
- typedef boost::unordered_map
- < KeyType , MappedType
- , boost::hash<KeyType> ,std::equal_to<KeyType>
- , ShmemAllocator>
- MyHashMap;
-
- //Construct a shared memory hash map.
- //Note that the first parameter is the initial bucket count and
- //after that, the hash function, the equality function and the allocator
- MyHashMap *myhashmap = segment.construct<MyHashMap>("MyHashMap") //object name
- ( 3, boost::hash<int>(), std::equal_to<int>() //
- , segment.get_allocator<ValueType>()); //allocator instance
-
- //Insert data in the hash map
- for(int i = 0; i < 100; ++i){
- myhashmap->insert(ValueType(i, (float)i));
- }
- }
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create shared memory
+ managed_shared_memory segment(create_only ,"MySharedMemory" ,65536);
+
+ //Note that unordered_map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
+ //so the allocator must allocate that pair.
+ typedef int KeyType;
+ typedef float MappedType;
+ typedef std::pair<const int, float> ValueType;
+
+ //Typedef the allocator
+ typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;
+
+ //Alias an unordered_map of ints that uses the previous STL-like allocator.
+ typedef boost::unordered_map
+ < KeyType , MappedType
+ , boost::hash<KeyType> ,std::equal_to<KeyType>
+ , ShmemAllocator>
+ MyHashMap;
+
+ //Construct a shared memory hash map.
+ //Note that the first parameter is the initial bucket count and
+ //after that, the hash function, the equality function and the allocator
+ MyHashMap *myhashmap = segment.construct<MyHashMap>("MyHashMap") //object name
+ ( 3, boost::hash<int>(), std::equal_to<int>() //
+ , segment.get_allocator<ValueType>()); //allocator instance
+
+ //Insert data in the hash map
+ for(int i = 0; i < 100; ++i){
+ myhashmap->insert(ValueType(i, (float)i));
}
- shared_memory_object::remove("MySharedMemory");
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_vectorstream.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_vectorstream.cpp (original)
+++ trunk/libs/interprocess/example/doc_vectorstream.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -30,83 +30,81 @@
int main ()
{
- //Create shared memory
- shared_memory_object::remove("MySharedMemory");
- try{
- managed_shared_memory segment(
- create_only,
- "MySharedMemory", //segment name
- 65536); //segment size in bytes
-
- //Construct shared memory vector
- MyVector *myvector =
- segment.construct<MyVector>("MyVector")
- (IntAllocator(segment.get_segment_manager()));
-
- //Fill vector
- myvector->reserve(100);
- for(int i = 0; i < 100; ++i){
- myvector->push_back(i);
- }
-
- //Create the vectorstream. To create the internal shared memory
- //basic_string we need to pass the shared memory allocator as
- //a constructor argument
- MyVectorStream myvectorstream(CharAllocator(segment.get_segment_manager()));
-
- //Reserve the internal string
- myvectorstream.reserve(100*5);
-
- //Write all vector elements as text in the internal string
- //Data will be directly written in shared memory, because
- //internal string's allocator is a shared memory allocator
- for(std::size_t i = 0, max = myvector->size(); i < max; ++i){
- myvectorstream << (*myvector)[i] << std::endl;
- }
-
- //Auxiliary vector to compare original data
- MyVector *myvector2 =
- segment.construct<MyVector>("MyVector2")
- (IntAllocator(segment.get_segment_manager()));
-
- //Avoid reallocations
- myvector2->reserve(100);
-
- //Extract all values from the internal
- //string directly to a shared memory vector.
- std::istream_iterator<int> it(myvectorstream), itend;
- std::copy(it, itend, std::back_inserter(*myvector2));
-
- //Compare vectors
- assert(std::equal(myvector->begin(), myvector->end(), myvector2->begin()));
-
- //Create a copy of the internal string
- MyString stringcopy (myvectorstream.vector());
-
- //Now we create a new empty shared memory string...
- MyString *mystring =
- segment.construct<MyString>("MyString")
- (CharAllocator(segment.get_segment_manager()));
-
- //...and we swap vectorstream's internal string
- //with the new one: after this statement mystring
- //will be the owner of the formatted data.
- //No reallocations, no data copies
- myvectorstream.swap_vector(*mystring);
-
- //Let's compare both strings
- assert(stringcopy == *mystring);
-
- //Done, destroy and delete vectors and string from the segment
- segment.destroy_ptr(myvector2);
- segment.destroy_ptr(myvector);
- segment.destroy_ptr(mystring);
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ managed_shared_memory segment(
+ create_only,
+ "MySharedMemory", //segment name
+ 65536); //segment size in bytes
+
+ //Construct shared memory vector
+ MyVector *myvector =
+ segment.construct<MyVector>("MyVector")
+ (IntAllocator(segment.get_segment_manager()));
+
+ //Fill vector
+ myvector->reserve(100);
+ for(int i = 0; i < 100; ++i){
+ myvector->push_back(i);
}
- catch(...){
- shared_memory_object::remove("MySharedMemory");
- throw;
+
+ //Create the vectorstream. To create the internal shared memory
+ //basic_string we need to pass the shared memory allocator as
+ //a constructor argument
+ MyVectorStream myvectorstream(CharAllocator(segment.get_segment_manager()));
+
+ //Reserve the internal string
+ myvectorstream.reserve(100*5);
+
+ //Write all vector elements as text in the internal string
+ //Data will be directly written in shared memory, because
+ //internal string's allocator is a shared memory allocator
+ for(std::size_t i = 0, max = myvector->size(); i < max; ++i){
+ myvectorstream << (*myvector)[i] << std::endl;
}
- shared_memory_object::remove("MySharedMemory");
+
+ //Auxiliary vector to compare original data
+ MyVector *myvector2 =
+ segment.construct<MyVector>("MyVector2")
+ (IntAllocator(segment.get_segment_manager()));
+
+ //Avoid reallocations
+ myvector2->reserve(100);
+
+ //Extract all values from the internal
+ //string directly to a shared memory vector.
+ std::istream_iterator<int> it(myvectorstream), itend;
+ std::copy(it, itend, std::back_inserter(*myvector2));
+
+ //Compare vectors
+ assert(std::equal(myvector->begin(), myvector->end(), myvector2->begin()));
+
+ //Create a copy of the internal string
+ MyString stringcopy (myvectorstream.vector());
+
+ //Now we create a new empty shared memory string...
+ MyString *mystring =
+ segment.construct<MyString>("MyString")
+ (CharAllocator(segment.get_segment_manager()));
+
+ //...and we swap vectorstream's internal string
+ //with the new one: after this statement mystring
+ //will be the owner of the formatted data.
+ //No reallocations, no data copies
+ myvectorstream.swap_vector(*mystring);
+
+ //Let's compare both strings
+ assert(stringcopy == *mystring);
+
+ //Done, destroy and delete vectors and string from the segment
+ segment.destroy_ptr(myvector2);
+ segment.destroy_ptr(myvector);
+ segment.destroy_ptr(mystring);
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_where_allocate.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_where_allocate.cpp (original)
+++ trunk/libs/interprocess/example/doc_where_allocate.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -29,45 +29,44 @@
MyShmStringVector;
//Open shared memory
- shared_memory_object::remove("myshm");
- try{
- managed_shared_memory shm(create_only, "myshm", 10000);
-
- //Create allocators
- CharAllocator charallocator (shm.get_segment_manager());
- StringAllocator stringallocator(shm.get_segment_manager());
-
- //This string is in only in this process (the pointer pointing to the
- //buffer that will hold the text is not in shared memory).
- //But the buffer that will hold "this is my text" is allocated from
- //shared memory
- MyShmString mystring(charallocator);
- mystring = "this is my text";
-
- //This vector is only in this process (the pointer pointing to the
- //buffer that will hold the MyShmString-s is not in shared memory).
- //But the buffer that will hold 10 MyShmString-s is allocated from
- //shared memory using StringAllocator. Since strings use a shared
- //memory allocator (CharAllocator) the 10 buffers that hold
- //"this is my text" text are also in shared memory.
- MyShmStringVector myvector(stringallocator);
- myvector.insert(myvector.begin(), 10, mystring);
-
- //This vector is fully constructed in shared memory. All pointers
- //buffers are constructed in the same shared memory segment
- //This vector can be safely accessed from other processes.
- MyShmStringVector *myshmvector =
- shm.construct<MyShmStringVector>("myshmvector")(stringallocator);
- myshmvector->insert(myshmvector->begin(), 10, mystring);
-
- //Destroy vector. This will free all strings that the vector contains
- shm.destroy_ptr(myshmvector);
- }
- catch(...){
- shared_memory_object::remove("myshm");
- throw;
- }
- shared_memory_object::remove("myshm");
+ //Remove shared memory on construction and destruction
+ struct shm_destroy
+ {
+ shm_destroy() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_destroy(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ managed_shared_memory shm(create_only, "MySharedMemory", 10000);
+
+ //Create allocators
+ CharAllocator charallocator (shm.get_segment_manager());
+ StringAllocator stringallocator(shm.get_segment_manager());
+
+ //This string is in only in this process (the pointer pointing to the
+ //buffer that will hold the text is not in shared memory).
+ //But the buffer that will hold "this is my text" is allocated from
+ //shared memory
+ MyShmString mystring(charallocator);
+ mystring = "this is my text";
+
+ //This vector is only in this process (the pointer pointing to the
+ //buffer that will hold the MyShmString-s is not in shared memory).
+ //But the buffer that will hold 10 MyShmString-s is allocated from
+ //shared memory using StringAllocator. Since strings use a shared
+ //memory allocator (CharAllocator) the 10 buffers that hold
+ //"this is my text" text are also in shared memory.
+ MyShmStringVector myvector(stringallocator);
+ myvector.insert(myvector.begin(), 10, mystring);
+
+ //This vector is fully constructed in shared memory. All pointers
+ //buffers are constructed in the same shared memory segment
+ //This vector can be safely accessed from other processes.
+ MyShmStringVector *myshmvector =
+ shm.construct<MyShmStringVector>("myshmvector")(stringallocator);
+ myshmvector->insert(myshmvector->begin(), 10, mystring);
+
+ //Destroy vector. This will free all strings that the vector contains
+ shm.destroy_ptr(myshmvector);
return 0;
}
//]
Modified: trunk/libs/interprocess/example/doc_windows_shared_memory.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_windows_shared_memory.cpp (original)
+++ trunk/libs/interprocess/example/doc_windows_shared_memory.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -8,41 +8,61 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#ifdef BOOST_WINDOWS
+#ifdef BOOST_INTERPROCESS_WINDOWS
+
//[doc_windows_shared_memory
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
#include <cstring>
+#include <cstdlib>
+#include <string>
-int main ()
+int main(int argc, char *argv[])
{
using namespace boost::interprocess;
- try{
+
+ if(argc == 1){ //Parent process
//Create a native windows shared memory object.
- windows_shared_memory shm (create_only, "shared_memory", read_write, 1000);
+ windows_shared_memory shm (create_only, "MySharedMemory", read_write, 1000);
//Map the whole shared memory in this process
mapped_region region(shm, read_write);
//Write all the memory to 1
- std::memset(region.get_address(), 1, 1000);
+ std::memset(region.get_address(), 1, region.get_size());
- //Launch the client process and wait until finishes...
- //...
+ //Launch child process
+ std::string s(argv[0]); s += " child";
+ if(0 != std::system(s.c_str()))
+ return 1;
+ //windows_shared_memory is destroyed when the last attached process dies...
}
- catch(interprocess_exception &ex){
- std::cout << ex.what() << std::endl;
- return 1;
+ else{
+ //Open already created shared memory object.
+ windows_shared_memory shm (open_only, "MySharedMemory", read_only);
+
+ //Map the whole shared memory in this process
+ mapped_region region(shm, read_only);
+
+ //Check that memory was initialized to 1
+ char *mem = static_cast<char*>(region.get_address());
+ for(std::size_t i = 0; i < region.get_size(); ++i)
+ if(*mem++ != 1)
+ return 1; //Error checking memory
+ return 0;
}
return 0;
}
//]
-#else //#ifdef BOOST_WINDOWS
+
+#else //BOOST_INTERPROCESS_WINDOWS
+
int main()
-{ return 0; }
-#endif//#ifdef BOOST_WINDOWS
+{
+ return 0;
+}
+
+#endif //BOOST_INTERPROCESS_WINDOWS
#include <boost/interprocess/detail/config_end.hpp>
Deleted: trunk/libs/interprocess/example/doc_windows_shared_memory2.cpp
==============================================================================
--- trunk/libs/interprocess/example/doc_windows_shared_memory2.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,55 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#ifdef BOOST_WINDOWS
-//[doc_windows_shared_memory2
-#include <boost/interprocess/windows_shared_memory.hpp>
-#include <boost/interprocess/mapped_region.hpp>
-#include <iostream>
-#include <cstring>
-
-int main ()
-{
- using namespace boost::interprocess;
- try{
- //Open already created shared memory object.
- windows_shared_memory shm(open_only, "shared_memory", read_only);
-
- //Map the whole shared memory in this process
- mapped_region region (shm, read_only);
-
- //Check that memory was initialized to 1
- const char *mem = static_cast<char*>(region.get_address());
- for(std::size_t i = 0; i < 1000; ++i){
- if(*mem++ != 1){
- std::cout << "Error checking memory!" << std::endl;
- return 1;
- }
- }
-
- std::cout << "Test successful!" << std::endl;
- }
- catch(interprocess_exception &ex){
- std::cout << "Unexpected exception: " << ex.what() << std::endl;
- return 1;
- }
-
- return 0;
-}
-//]
-#else //#ifdef BOOST_WINDOWS
-int main()
-{ return 0; }
-#endif//#ifdef BOOST_WINDOWS
-
-#include <boost/interprocess/detail/config_end.hpp>
-
Modified: trunk/libs/interprocess/proj/to-do.txt
==============================================================================
--- trunk/libs/interprocess/proj/to-do.txt (original)
+++ trunk/libs/interprocess/proj/to-do.txt 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1,5 +1,3 @@
--> change rvalue reference signatures in all containers
-
-> add private_read_only to mapped_region to support MAP_PRIVATE plus PROT_READ
-> add contiguous_elements option to burst allocation
@@ -43,28 +41,26 @@
-> barrier_test fails on MacOS X on PowerPC.
-->use virtual functions to minimize template explosion in managed classes
+-> use virtual functions to minimize template explosion in managed classes
-->Insertions with InpIt are not tested in containers
+-> Insertions with InpIt are not tested in containers
-->Run tests with rvalue reference compilers with no variadic insertions
+-> Run tests with rvalue reference compilers with no variadic insertions
-->find a way to pass security attributes to shared memory
+-> find a way to pass security attributes to shared memory
-->Explain in docs that shared memory can't be used between different users in windows
+-> Explain in docs that shared memory can't be used between different users in windows
-> Implement vector with memcpy/memmove for trivially copyable types.
--> Update all swap() calls to work with rvalues in all classes
-
--> correct swap overloads for the documentation so that just appears a single rvalue swap
-
--> correct splice()/merg overloads for the documentation so that just appears a single rvalue splice
-
-> flat_xxx constructors are not documented
-> operator >> eta antzekoek moved_value behar dute
--> make file_lock movable
-
-> Add cmath workaround for Boost < 1.37
+
+-> rvalue reference enabled compilers are not optimized with is_movable and move_iterator
+
+-> Add allocator test template that test all new functions (allocate_many, etc.)
+
+-> MacOS shm_open is non-conformant. Is there a way to know the size of a shared memory object?
Modified: trunk/libs/interprocess/proj/vc7ide/Interprocess.sln
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/Interprocess.sln (original)
+++ trunk/libs/interprocess/proj/vc7ide/Interprocess.sln 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -103,18 +103,6 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_contA", "doc_contA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792652}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_contB", "doc_contB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792651}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory", "doc_shared_memory.vcproj", "{58CCE183-6032-12FE-4FC7-83A79F760B61}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_test", "unique_ptr_test.vcproj", "{571C3383-6092-A877-1238-B3786BAE7605}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -139,14 +127,6 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory2", "doc_shared_memory2.vcproj", "{58CE1D83-F31E-4FD7-6132-8A79F6307B61}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_mapping2", "doc_file_mapping2.vcproj", "{5CE19883-F413-7EFD-6342-B79639F7B611}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_mapping", "doc_file_mapping.vcproj", "{58DE18C3-3261-2F3E-FD47-83760B9FA761}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -223,10 +203,6 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_windows_shared_memory2", "doc_windows_shared_memory2.vcproj", "{5E1D6C83-31DE-4F6F-6132-87A9FB663041}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_node_pool_test", "adaptive_node_pool_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -295,26 +271,10 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_messageA", "doc_ipc_messageA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792649}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_messageB", "doc_ipc_messageB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792648}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_mapped_file", "doc_managed_mapped_file.vcproj", "{58CCE183-5091-48FE-A4FC-BA0D3A792446}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_allocA", "doc_named_allocA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792645}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_allocB", "doc_named_allocB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792644}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_offset_ptr", "doc_offset_ptr.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792643}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -463,11 +423,33 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stable_vector_test", "stable_vector_test.vcproj", "{5E11C8D3-FA52-760A-84FE-943A6BA05A21}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_spawn_vector", "doc_spawn_vector.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792652}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_message", "doc_ipc_message.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792649}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_alloc", "doc_named_alloc.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792645}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory", "doc_shared_memory.vcproj", "{58CCE183-6032-12FE-4FC7-83A79F760B61}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.ActiveCfg = Debug|Win32
{5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.Build.0 = Debug|Win32
@@ -573,18 +555,6 @@
{58CCE183-6092-48FE-A4F7-BA0D3A792653}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792653}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792653}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Release.Build.0 = Release|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.Build.0 = Debug|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.ActiveCfg = Release|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.Build.0 = Release|Win32
{571C3383-6092-A877-1238-B3786BAE7605}.Debug.ActiveCfg = Debug|Win32
{571C3383-6092-A877-1238-B3786BAE7605}.Debug.Build.0 = Debug|Win32
{571C3383-6092-A877-1238-B3786BAE7605}.Release.ActiveCfg = Release|Win32
@@ -609,14 +579,6 @@
{5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Debug.Build.0 = Debug|Win32
{5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Release.ActiveCfg = Release|Win32
{5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Release.Build.0 = Release|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Debug.ActiveCfg = Debug|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Debug.Build.0 = Debug|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Release.ActiveCfg = Release|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Release.Build.0 = Release|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Debug.ActiveCfg = Debug|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Debug.Build.0 = Debug|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Release.ActiveCfg = Release|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Release.Build.0 = Release|Win32
{58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.ActiveCfg = Debug|Win32
{58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.Build.0 = Debug|Win32
{58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.ActiveCfg = Release|Win32
@@ -693,10 +655,6 @@
{5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Debug.Build.0 = Debug|Win32
{5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Release.ActiveCfg = Release|Win32
{5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Release.Build.0 = Release|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Debug.ActiveCfg = Debug|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Debug.Build.0 = Debug|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Release.ActiveCfg = Release|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Release.Build.0 = Release|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
@@ -765,26 +723,10 @@
{5E18CC83-6092-48FE-A677-B832A0D3A650}.Debug.Build.0 = Debug|Win32
{5E18CC83-6092-48FE-A677-B832A0D3A650}.Release.ActiveCfg = Release|Win32
{5E18CC83-6092-48FE-A677-B832A0D3A650}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Release.Build.0 = Release|Win32
{58CCE183-5091-48FE-A4FC-BA0D3A792446}.Debug.ActiveCfg = Debug|Win32
{58CCE183-5091-48FE-A4FC-BA0D3A792446}.Debug.Build.0 = Debug|Win32
{58CCE183-5091-48FE-A4FC-BA0D3A792446}.Release.ActiveCfg = Release|Win32
{58CCE183-5091-48FE-A4FC-BA0D3A792446}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792643}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792643}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792643}.Release.ActiveCfg = Release|Win32
@@ -933,6 +875,26 @@
{5183C8CE-F2E1-3620-237A-B765C9896390}.Debug.Build.0 = Debug|Win32
{5183C8CE-F2E1-3620-237A-B765C9896390}.Release.ActiveCfg = Release|Win32
{5183C8CE-F2E1-3620-237A-B765C9896390}.Release.Build.0 = Release|Win32
+ {5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Debug.ActiveCfg = Debug|Win32
+ {5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Debug.Build.0 = Debug|Win32
+ {5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Release.ActiveCfg = Release|Win32
+ {5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.Build.0 = Release|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
Modified: trunk/libs/interprocess/proj/vc7ide/adaptive_node_pool_test.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/adaptive_node_pool_test.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/adaptive_node_pool_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,6 +21,7 @@
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
Modified: trunk/libs/interprocess/proj/vc7ide/doc_adaptive_pool.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_adaptive_pool.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_adaptive_pool.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_adaptive_pool.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{7D15CE80-A945-7643-19A6-6BB4B2F13597}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_allocator.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_allocator.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_allocator.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_allocator.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{7A713380-C945-4764-A066-625BE5EABBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionA.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4BE2BEF1-C8A9-53BC-1A02-952FFA2D75A2}">
<File
- RelativePath="..\..\example\doc_anonymous_conditionA.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_conditionA.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{913380FA-5C7A-7644-A568-62F585B5FBCB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_conditionB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4B2EF711-14CA-5347-F025-7F75AF2D22A2}">
<File
- RelativePath="..\..\example\doc_anonymous_conditionB.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_conditionB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{92431970-57CA-4ED4-85A6-624258635BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexA.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4BE712F1-C98A-4537-12A0-72D752FFA2A2}">
<File
- RelativePath="..\..\example\doc_anonymous_mutexA.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_mutexA.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91243380-C57A-4764-A856-625FEF585BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_mutexB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4B712EF1-98CA-4537-A012-72D2FF75A2A2}">
<File
- RelativePath="..\..\example\doc_anonymous_mutexB.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_mutexB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91243970-C57A-4624-A856-625142585BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreA.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4BEFCAB1-8AC0-3B5C-AF1B-9522D75AFFA2}">
<File
- RelativePath="..\..\example\doc_anonymous_semaphoreA.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_semaphoreA.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{918033FA-7644-7A5C-AFB8-62FB5FA585CB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_semaphoreB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4BCDF711-5717-14CA-F250-F2D8F75A22A2}">
<File
- RelativePath="..\..\example\doc_anonymous_semaphoreB.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_semaphoreB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{94310A70-5A86-5BFA-4ED4-62FEF535B86B}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_shared_memory.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_shared_memory.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_shared_memory.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_anonymous_shared_memory.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{95431998-8EB8-9BCA-44D0-ECD5A7BE2B52}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexA.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4BF1E712-4FB5-08CB-2A11-752DCD72F2B2}">
<File
- RelativePath="..\..\example\doc_anonymous_upgradable_mutexA.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_upgradable_mutexA.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{98238D43-76A8-57CB-4764-E5F572E85BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_anonymous_upgradable_mutexB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4B712E2E-5347-A352-8C9F-FF72D27982A2}">
<File
- RelativePath="..\..\example\doc_anonymous_upgradable_mutexB.cpp">
+ RelativePath="..\..\example\comp_doc_anonymous_upgradable_mutexB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91991243-4624-C67A-B5A6-3E2DA5514BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_bufferstream.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_bufferstream.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_bufferstream.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_bufferstream.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{94323380-C57A-4764-A066-625FBE585BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_cached_adaptive_pool.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_cached_adaptive_pool.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_cached_adaptive_pool.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_cached_adaptive_pool.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{5CEE7180-8A7D-6473-19A6-6DC4B21C3597}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_cached_node_allocator.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_cached_node_allocator.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_cached_node_allocator.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_cached_node_allocator.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{715E8BE0-5A67-5863-6B26-295FE5A71C4A}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_cont.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_cont.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_cont.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_cont.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_contB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_contB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_contB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
- RelativePath="..\..\example\doc_contB.cpp">
+ RelativePath="..\..\example\comp_doc_contB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_file_mapping.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_file_mapping.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_file_mapping.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_file_mapping.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{53F4F538-D8DB-D441-8EB8-E5A36242F2FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Deleted: trunk/libs/interprocess/proj/vc7ide/doc_file_mapping2.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_file_mapping2.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="doc_file_mapping2"
- ProjectGUID="{5CE19883-F413-7EFD-6342-B79639F7B611}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="../../Bin/Win32/Debug"
- IntermediateDirectory="Debug/doc_file_mapping2"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_file_mapping2_d.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/doc_file_mapping2.pdb"
- SubSystem="1"
- TargetMachine="1"
- FixedBaseAddress="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="../../Bin/Win32/Release"
- IntermediateDirectory="Release/doc_file_mapping2"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- RuntimeLibrary="2"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_file_mapping2.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4051D7FF-CADB-4960-1663-2FE242B357FF}">
- <File
- RelativePath="..\..\example\doc_file_mapping2.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{94937728-D6AE-6637-8EB8-BF26E56AC2FB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_intrusive.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_intrusive.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_intrusive.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_intrusive.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93295380-89BD-4b04-88EB-6225BE5faBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Added: trunk/libs/interprocess/proj/vc7ide/doc_ipc_message.vcproj
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/proj/vc7ide/doc_ipc_message.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="doc_ipc_message"
+ ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792649}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../Bin/Win32/Debug"
+ IntermediateDirectory="Debug/doc_ipc_message"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/doc_ipc_message_d.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/doc_ipc_message.pdb"
+ SubSystem="1"
+ TargetMachine="1"
+ FixedBaseAddress="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../Bin/Win32/Release"
+ IntermediateDirectory="Release/doc_ipc_message"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ RuntimeLibrary="2"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/doc_ipc_message.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\example\doc_ipc_message.cpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Deleted: trunk/libs/interprocess/proj/vc7ide/doc_ipc_messageA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_ipc_messageA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="doc_ipc_messageA"
- ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792649}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="../../Bin/Win32/Debug"
- IntermediateDirectory="Debug/doc_ipc_messageA"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_ipc_messageA_d.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/doc_ipc_messageA.pdb"
- SubSystem="1"
- TargetMachine="1"
- FixedBaseAddress="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="../../Bin/Win32/Release"
- IntermediateDirectory="Release/doc_ipc_messageA"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- RuntimeLibrary="2"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_ipc_messageA.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
- <File
- RelativePath="..\..\example\doc_ipc_messageA.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
Deleted: trunk/libs/interprocess/proj/vc7ide/doc_ipc_messageB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_ipc_messageB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="doc_ipc_messageB"
- ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792648}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="../../Bin/Win32/Debug"
- IntermediateDirectory="Debug/doc_ipc_messageB"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_ipc_messageB_d.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/doc_ipc_messageB.pdb"
- SubSystem="1"
- TargetMachine="1"
- FixedBaseAddress="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="../../Bin/Win32/Release"
- IntermediateDirectory="Release/doc_ipc_messageB"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- RuntimeLibrary="2"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_ipc_messageB.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
- <File
- RelativePath="..\..\example\doc_ipc_messageB.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_aligned_allocation.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_aligned_allocation.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_aligned_allocation.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_managed_aligned_allocation.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{57613F38-DC8B-43D1-8EB8-E53642BF23FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_allocation_command.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_allocation_command.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_allocation_command.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_managed_allocation_command.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{53F54618-D3BA-1D51-A89E-E51FABD7E2FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_construction_info.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_construction_info.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_construction_info.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_managed_construction_info.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{55274F38-8C8B-D461-55EB-E53642BF23FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_grow.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_grow.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_grow.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -128,11 +128,6 @@
RelativePath="..\..\example\doc_managed_grow.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{351E556C-18B7-6CD8-3B17-D31DEFB6F91B}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_heap_memory.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_heap_memory.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_heap_memory.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_managed_heap_memory.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_mapped_file.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_mapped_file.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_mapped_file.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_managed_mapped_file.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_multiple_allocation.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_multiple_allocation.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_multiple_allocation.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -128,11 +128,6 @@
RelativePath="..\..\example\doc_managed_multiple_allocation.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{53F36518-6D8C-3B17-8B71-D5632DF213FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_managed_raw_allocation.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_managed_raw_allocation.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_managed_raw_allocation.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_managed_raw_allocation.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{3FE55338-8DCB-4D41-EB98-EA32F42724FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_map.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_map.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_map.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_map.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{95918340-89BD-9E04-8B4C-6242E76FBEFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_message_queueA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_message_queueA.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_message_queueA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{42FBE7AD-C8A9-12A0-5347-72FFA25175A2}">
<File
- RelativePath="..\..\example\doc_message_queueA.cpp">
+ RelativePath="..\..\example\comp_doc_message_queueA.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91434280-4764-C57A-B956-625855FEFCAB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_message_queueB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_message_queueB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_message_queueB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{412EC7F1-45A7-98CA-A012-7952A2D2AFF2}">
<File
- RelativePath="..\..\example\doc_message_queueB.cpp">
+ RelativePath="..\..\example\comp_doc_message_queueB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{92437370-6244-D57A-A856-645251825CDB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_move_containers.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_move_containers.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_move_containers.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_move_containers.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{942CA380-C57A-16A6-4764-625A25BD78FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Added: trunk/libs/interprocess/proj/vc7ide/doc_named_alloc.vcproj
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/proj/vc7ide/doc_named_alloc.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="doc_named_alloc"
+ ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792645}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../Bin/Win32/Debug"
+ IntermediateDirectory="Debug/doc_named_alloc"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/doc_named_alloc_d.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/doc_named_alloc.pdb"
+ SubSystem="1"
+ TargetMachine="1"
+ FixedBaseAddress="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../Bin/Win32/Release"
+ IntermediateDirectory="Release/doc_named_alloc"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ RuntimeLibrary="2"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/doc_named_alloc.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\example\doc_named_alloc.cpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Deleted: trunk/libs/interprocess/proj/vc7ide/doc_named_allocA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_named_allocA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="doc_named_allocA"
- ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792645}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="../../Bin/Win32/Debug"
- IntermediateDirectory="Debug/doc_named_allocA"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_named_allocA_d.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/doc_named_allocA.pdb"
- SubSystem="1"
- TargetMachine="1"
- FixedBaseAddress="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="../../Bin/Win32/Release"
- IntermediateDirectory="Release/doc_named_allocA"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- RuntimeLibrary="2"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_named_allocA.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
- <File
- RelativePath="..\..\example\doc_named_allocA.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
Deleted: trunk/libs/interprocess/proj/vc7ide/doc_named_allocB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_named_allocB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
+++ (empty file)
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="doc_named_allocB"
- ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792644}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="../../Bin/Win32/Debug"
- IntermediateDirectory="Debug/doc_named_allocB"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_named_allocB_d.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/doc_named_allocB.pdb"
- SubSystem="1"
- TargetMachine="1"
- FixedBaseAddress="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="../../Bin/Win32/Release"
- IntermediateDirectory="Release/doc_named_allocB"
- ConfigurationType="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="../../../.."
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
- RuntimeLibrary="2"
- TreatWChar_tAsBuiltInType="TRUE"
- ForceConformanceInForLoopScope="FALSE"
- UsePrecompiledHeader="0"
- WarningLevel="4"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_named_allocB.exe"
- LinkIncremental="1"
- AdditionalLibraryDirectories="../../../../stage/lib"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
- <File
- RelativePath="..\..\example\doc_named_allocB.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_named_conditionA.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_named_conditionA.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_named_conditionA.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{AB2F71E1-2E95-7FA3-2A10-741FA12A22F2}">
<File
- RelativePath="..\..\example\doc_named_conditionA.cpp">
+ RelativePath="..\..\example\comp_doc_named_conditionA.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91553810-7ECB-6474-5A96-62EF51EBABFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_named_conditionB.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_named_conditionB.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_named_conditionB.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{AB712FE1-92E5-7543-12A0-74522FFA12A2}">
<File
- RelativePath="..\..\example\doc_named_conditionB.cpp">
+ RelativePath="..\..\example\comp_doc_named_conditionB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91815530-7C5B-6744-5A86-62EF51EEFBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_named_mutex.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_named_mutex.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_named_mutex.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_named_mutex.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{91338150-57CA-4674-85A6-6216EFEF5BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_node_allocator.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_node_allocator.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_node_allocator.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_node_allocator.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{7AED1580-4A95-7643-A066-625BFB21B49B}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_offset_ptr.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_offset_ptr.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_offset_ptr.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_offset_ptr.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_private_adaptive_pool.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_private_adaptive_pool.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_private_adaptive_pool.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_private_adaptive_pool.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{74CE8C10-A845-3F67-19A6-6BF1327B28B7}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_private_node_allocator.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_private_node_allocator.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_private_node_allocator.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_private_node_allocator.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{7D15E8B0-45A7-6573-26A6-25FE5EA7149B}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_scoped_ptr.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_scoped_ptr.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_scoped_ptr.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_scoped_ptr.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93295380-89BD-4b04-88EB-6225BE5faBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_shared_memory.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_shared_memory.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_shared_memory.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_shared_memory.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93909538-DA9B-44D0-8EB8-E55F262BEBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_shared_ptr.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93483B80-D995-C044-8BEB-625F27A58BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr_explicit.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr_explicit.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_shared_ptr_explicit.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_shared_ptr_explicit.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{483B9380-8BEB-D795-C194-6A5B62EF27FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Added: trunk/libs/interprocess/proj/vc7ide/doc_spawn_vector.vcproj
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/proj/vc7ide/doc_spawn_vector.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="doc_spawn_vector"
+ ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D3A792652}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../Bin/Win32/Debug"
+ IntermediateDirectory="Debug/doc_spawn_vector"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/doc_spawn_vector_d.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/doc_spawn_vector.pdb"
+ SubSystem="1"
+ TargetMachine="1"
+ FixedBaseAddress="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../Bin/Win32/Release"
+ IntermediateDirectory="Release/doc_spawn_vector"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ RuntimeLibrary="2"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/doc_spawn_vector.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath="..\..\example\doc_spawn_vector.cpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_unique_ptr.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_unique_ptr.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_unique_ptr.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_unique_ptr.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93B21880-3646-C044-BF6B-621F27BA58B2}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_vectorstream.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_vectorstream.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_vectorstream.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_vectorstream.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{94323380-89BD-4764-818B-625FBE585BFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_where_allocate.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_where_allocate.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_where_allocate.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_where_allocate.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93295380-89BD-4b04-88EB-6225BE5faBFB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,11 +127,6 @@
RelativePath="..\..\example\doc_windows_shared_memory.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93908538-DA9B-4D30-B88E-E5A22B4252FB}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory2.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory2.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/doc_windows_shared_memory2.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -39,7 +39,7 @@
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/doc_windows_shared_memory2.pdb"
+ ProgramDatabaseFile="$(OutDir)/doc_windows_shared_memoryB.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
@@ -86,7 +86,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/doc_windows_shared_memory2.exe"
+ OutputFile="$(OutDir)/doc_windows_shared_memoryB.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
@@ -124,14 +124,9 @@
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{437F71DF-CA9B-6637-0366-3E52D735BAFF}">
<File
- RelativePath="..\..\example\doc_windows_shared_memory2.cpp">
+ RelativePath="..\..\example\comp_doc_windows_shared_memoryB.cpp">
</File>
</Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{49819248-6ABD-4E40-B98E-6AC2EFB21B26}">
- </Filter>
</Files>
<Globals>
</Globals>
Modified: trunk/libs/interprocess/proj/vc7ide/interprocesslib.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/interprocesslib.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/interprocesslib.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -120,24 +120,14 @@
RelativePath="..\..\..\..\boost\interprocess\containers\slist.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\containers\stable_vector.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\containers\string.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\containers\vector.hpp">
</File>
- <Filter
- Name="detail"
- Filter="">
- <File
- RelativePath="..\..\..\..\boost\interprocess\containers\detail\flat_tree.hpp">
- </File>
- <File
- RelativePath="..\..\..\..\boost\interprocess\containers\detail\node_alloc_holder.hpp">
- </File>
- <File
- RelativePath="..\..\..\..\boost\interprocess\containers\detail\tree.hpp">
- </File>
- </Filter>
</Filter>
<Filter
Name="Allocators"
@@ -346,6 +336,9 @@
RelativePath="..\..\..\..\boost\interprocess\managed_windows_shared_memory.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\managed_xsi_shared_memory.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\mapped_region.hpp">
</File>
<File
@@ -362,18 +355,9 @@
Name="Detail"
Filter="">
<File
- RelativePath="..\..\..\..\boost\interprocess\detail\advanced_insert_int.hpp">
- </File>
- <File
- RelativePath="..\..\..\..\boost\interprocess\detail\algorithms.hpp">
- </File>
- <File
RelativePath="..\..\..\..\boost\interprocess\detail\atomic.hpp">
</File>
<File
- RelativePath="..\..\..\..\boost\interprocess\detail\basic_segment_manager.hpp">
- </File>
- <File
RelativePath="..\..\..\..\boost\interprocess\detail\cast_tags.hpp">
</File>
<File
@@ -386,9 +370,6 @@
RelativePath="..\..\..\..\boost\interprocess\detail\file_wrapper.hpp">
</File>
<File
- RelativePath="..\..\..\..\boost\interprocess\detail\gcd_lcm.hpp">
- </File>
- <File
RelativePath="..\..\..\..\boost\interprocess\detail\in_place_interface.hpp">
</File>
<File
@@ -398,9 +379,6 @@
RelativePath="..\..\..\..\boost\interprocess\detail\intersegment_ptr.hpp">
</File>
<File
- RelativePath="..\..\..\..\boost\interprocess\detail\iterators.hpp">
- </File>
- <File
RelativePath="..\..\..\..\boost\interprocess\detail\managed_memory_impl.hpp">
</File>
<File
@@ -419,9 +397,6 @@
RelativePath="..\..\..\..\boost\interprocess\detail\move.hpp">
</File>
<File
- RelativePath="..\..\..\..\boost\interprocess\detail\move_iterator.hpp">
- </File>
- <File
RelativePath="..\..\..\..\boost\interprocess\detail\mpl.hpp">
</File>
<File
@@ -455,6 +430,9 @@
RelativePath="..\..\..\..\boost\interprocess\detail\tmp_dir_helpers.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\transform_iterator.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\type_traits.hpp">
</File>
<File
@@ -464,9 +442,6 @@
RelativePath="..\..\..\..\boost\interprocess\detail\variadic_templates_tools.hpp">
</File>
<File
- RelativePath="..\..\..\..\boost\interprocess\detail\version_type.hpp">
- </File>
- <File
RelativePath="..\..\..\..\boost\interprocess\detail\win32_api.hpp">
</File>
<File
Modified: trunk/libs/interprocess/proj/vc7ide/shared_memory_mappable_test.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/shared_memory_mappable_test.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/shared_memory_mappable_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -22,9 +22,11 @@
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
+ KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
+ DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
Added: trunk/libs/interprocess/proj/vc7ide/stable_vector_test.vcproj
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/proj/vc7ide/stable_vector_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="stable_vector_test"
+ ProjectGUID="{5E11C8D3-FA52-760A-84FE-943A6BA05A21}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../Bin/Win32/Debug"
+ IntermediateDirectory="Debug/stable_vector_test"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/stable_vector_test_d.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/stable_vector_test.pdb"
+ SubSystem="1"
+ TargetMachine="1"
+ FixedBaseAddress="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../Bin/Win32/Release"
+ IntermediateDirectory="Release/stable_vector_test"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ RuntimeLibrary="2"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="FALSE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib"
+ OutputFile="$(OutDir)/stable_vector_test.exe"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../../stage/lib"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{37BC807F-2451-A306-7AC5-7A35A32A22DF}">
+ <File
+ RelativePath="..\..\test\stable_vector_test.cpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Modified: trunk/libs/interprocess/proj/vc7ide/string_test.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/string_test.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/string_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,6 +21,7 @@
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+ GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
Modified: trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_mapping_test.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_mapping_test.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_mapping_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -13,7 +13,7 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
- IntermediateDirectory="Debug/windows_windows_shared_memory_mapping_test"
+ IntermediateDirectory="Debug/windows_shared_memory_mapping_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -39,7 +39,7 @@
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/windows_windows_shared_memory_mapping_test.pdb"
+ ProgramDatabaseFile="$(OutDir)/windows_shared_memory_mapping_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
@@ -67,7 +67,7 @@
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
- IntermediateDirectory="Release/windows_windows_shared_memory_mapping_test"
+ IntermediateDirectory="Release/windows_shared_memory_mapping_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
@@ -87,7 +87,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/windows_windows_shared_memory_mapping_test.exe"
+ OutputFile="$(OutDir)/windows_shared_memory_mapping_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
Modified: trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_test.vcproj
==============================================================================
--- trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_test.vcproj (original)
+++ trunk/libs/interprocess/proj/vc7ide/windows_shared_memory_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="7.10"
Name="windows_shared_memory_test"
- ProjectGUID="{E385C28C-0691-4FA7-F48E-935BA0D06310}"
+ ProjectGUID="{E35C288C-F48E-6914-4FA7-5BA006383C10}"
Keyword="Win32Proj">
<Platforms>
<Platform
@@ -35,7 +35,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
- OutputFile="$(OutDir)/shared_memory_test_d.exe"
+ OutputFile="$(OutDir)/windows_shared_memory_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
Modified: trunk/libs/interprocess/test/adaptive_node_pool_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/adaptive_node_pool_test.cpp (original)
+++ trunk/libs/interprocess/test/adaptive_node_pool_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -7,6 +7,7 @@
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
+
#include <boost/interprocess/detail/config_begin.hpp>
#include "node_pool_test.hpp"
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
Modified: trunk/libs/interprocess/test/allocator_v1.hpp
==============================================================================
--- trunk/libs/interprocess/test/allocator_v1.hpp (original)
+++ trunk/libs/interprocess/test/allocator_v1.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -18,10 +18,12 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/pointer_to_other.hpp>
+
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <memory>
#include <algorithm>
@@ -49,10 +51,10 @@
typedef typename segment_manager::void_pointer aux_pointer_t;
typedef typename
- detail::pointer_to_other
+ boost::pointer_to_other
<aux_pointer_t, const void>::type cvoid_ptr;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<cvoid_ptr, segment_manager>::type alloc_ptr_t;
template<class T2, class SegmentManager2>
@@ -64,9 +66,9 @@
public:
typedef T value_type;
- typedef typename detail::pointer_to_other
+ typedef typename boost::pointer_to_other
<cvoid_ptr, T>::type pointer;
- typedef typename detail::
+ typedef typename boost::
pointer_to_other<pointer, const T>::type const_pointer;
typedef typename detail::add_reference
<value_type>::type reference;
Modified: trunk/libs/interprocess/test/check_equal_containers.hpp
==============================================================================
--- trunk/libs/interprocess/test/check_equal_containers.hpp (original)
+++ trunk/libs/interprocess/test/check_equal_containers.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -32,10 +32,12 @@
typename MyShmCont::iterator itshm(shmcont->begin()), itshmend(shmcont->end());
typename MyStdCont::iterator itstd(stdcont->begin());
- if((typename MyStdCont::size_type)std::distance(itshm, itshmend) != shmcont->size()){
+ typename MyStdCont::size_type dist = (typename MyStdCont::size_type)std::distance(itshm, itshmend);
+ if(dist != shmcont->size()){
return false;
}
- for(; itshm != itshmend; ++itshm, ++itstd){
+ std::size_t i = 0;
+ for(; itshm != itshmend; ++itshm, ++itstd, ++i){
value_type val(*itstd);
const value_type &v = *itshm;
if(v != val)
Modified: trunk/libs/interprocess/test/data_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/data_test.cpp (original)
+++ trunk/libs/interprocess/test/data_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,7 +17,6 @@
#include <algorithm>
#include <functional>
#include <string>
-#include <cstdio> //std::remove
#include "print_container.hpp"
#include "get_process_id_name.hpp"
@@ -29,8 +28,6 @@
std::string process_name;
test::get_process_id_name(process_name);
const char *const shMemName = process_name.c_str();
- std::string filename (test::get_process_id_name());
- filename += "_file";
try{
shared_memory_object::remove(shMemName);
@@ -90,12 +87,9 @@
res = (0 == segment.find<MyVect>(allocName).first);
if(!res)
return 1;
-
- std::remove(filename.c_str());
}
}
catch(...){
- std::remove(filename.c_str());
shared_memory_object::remove(shMemName);
throw;
}
Modified: trunk/libs/interprocess/test/deque_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/deque_test.cpp (original)
+++ trunk/libs/interprocess/test/deque_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -26,7 +26,6 @@
#include <boost/interprocess/allocators/allocator.hpp>
#include "allocator_v1.hpp"
#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/move_iterator.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
@@ -67,12 +66,12 @@
{
IntType move_me(1);
stddeque->insert(stddeque->begin()+size/2, 50, 1);
- shmdeque->insert(shmdeque->begin()+size/2, 50, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->begin()+size/2, 50, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
{
IntType move_me(2);
- shmdeque->assign(shmdeque->size()/2, detail::move_impl(move_me));
+ shmdeque->assign(shmdeque->size()/2, boost::interprocess::move(move_me));
stddeque->assign(stddeque->size()/2, 2);
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
@@ -81,13 +80,13 @@
stddeque->clear();
shmdeque->clear();
stddeque->insert(stddeque->begin(), 50, 1);
- shmdeque->insert(shmdeque->begin(), 50, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->begin(), 50, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
stddeque->insert(stddeque->begin()+20, 50, 1);
- shmdeque->insert(shmdeque->begin()+20, 50, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->begin()+20, 50, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
stddeque->insert(stddeque->begin()+20, 20, 1);
- shmdeque->insert(shmdeque->begin()+20, 20, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->begin()+20, 20, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
{
@@ -95,13 +94,13 @@
stddeque->clear();
shmdeque->clear();
stddeque->insert(stddeque->end(), 50, 1);
- shmdeque->insert(shmdeque->end(), 50, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->end(), 50, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
stddeque->insert(stddeque->end()-20, 50, 1);
- shmdeque->insert(shmdeque->end()-20, 50, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->end()-20, 50, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
stddeque->insert(stddeque->end()-20, 20, 1);
- shmdeque->insert(shmdeque->end()-20, 20, detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->end()-20, 20, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
@@ -127,10 +126,9 @@
{
//Now test move semantics
deque<recursive_deque> original;
- deque<recursive_deque> move_ctor(detail::move_impl(original));
+ deque<recursive_deque> move_ctor(boost::interprocess::move(original));
deque<recursive_deque> move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
@@ -174,7 +172,7 @@
int i;
for(i = 0; i < max*100; ++i){
IntType move_me(i);
- shmdeque->insert(shmdeque->end(), detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->end(), boost::interprocess::move(move_me));
stddeque->insert(stddeque->end(), i);
}
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
@@ -184,7 +182,7 @@
for(i = 0; i < max*100; ++i){
IntType move_me(i);
- shmdeque->push_back(detail::move_impl(move_me));
+ shmdeque->push_back(boost::interprocess::move(move_me));
stddeque->push_back(i);
}
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
@@ -194,7 +192,7 @@
for(i = 0; i < max*100; ++i){
IntType move_me(i);
- shmdeque->push_front(detail::move_impl(move_me));
+ shmdeque->push_front(boost::interprocess::move(move_me));
stddeque->push_front(i);
}
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
@@ -215,7 +213,7 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me (-1);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
@@ -223,8 +221,8 @@
}
shmdeque->insert(shmdeque->end()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(aux_vect + 50));
+ ,boost::interprocess::make_move_iterator(&aux_vect[0])
+ ,boost::interprocess::make_move_iterator(aux_vect + 50));
stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
@@ -238,21 +236,21 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmdeque->insert(shmdeque->begin()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(aux_vect + 50));
+ ,boost::interprocess::make_move_iterator(&aux_vect[0])
+ ,boost::interprocess::make_move_iterator(aux_vect + 50));
stddeque->insert(stddeque->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
}
if(!copyable_only(shmdeque, stddeque
- ,detail::bool_<!is_movable<IntType>::value>())){
+ ,detail::bool_<!boost::interprocess::is_movable<IntType>::value>())){
return false;
}
@@ -263,7 +261,7 @@
for(i = 0; i < max; ++i){
IntType move_me(i);
- shmdeque->insert(shmdeque->begin(), detail::move_impl(move_me));
+ shmdeque->insert(shmdeque->begin(), boost::interprocess::move(move_me));
stddeque->insert(stddeque->begin(), i);
}
if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
Modified: trunk/libs/interprocess/test/dummy_test_allocator.hpp
==============================================================================
--- trunk/libs/interprocess/test/dummy_test_allocator.hpp (original)
+++ trunk/libs/interprocess/test/dummy_test_allocator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,10 +19,10 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <memory>
#include <algorithm>
@@ -64,7 +64,7 @@
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
-// typedef detail::version_type<dummy_test_allocator, 2> version;
+// typedef boost::interprocess::version_type<dummy_test_allocator, 2> version;
template<class T2>
struct rebind
@@ -111,7 +111,7 @@
//Experimental version 2 dummy_test_allocator functions
std::pair<pointer, bool>
- allocation_command(allocation_type,
+ allocation_command(boost::interprocess::allocation_type,
size_type,
size_type,
size_type &, const pointer & = 0)
Modified: trunk/libs/interprocess/test/emplace_test.hpp
==============================================================================
--- trunk/libs/interprocess/test/emplace_test.hpp (original)
+++ trunk/libs/interprocess/test/emplace_test.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -29,27 +29,18 @@
EmplaceInt& operator=(const EmplaceInt &o);
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(EmplaceInt)
+
EmplaceInt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0)
: a_(a), b_(b), c_(c), d_(d), e_(e)
{}
- #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- EmplaceInt(EmplaceInt &&o)
+ EmplaceInt(BOOST_INTERPROCESS_RV_REF(EmplaceInt) o)
: a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
- #else
- EmplaceInt(detail::moved_object<EmplaceInt> mo)
- : a_(mo.get().a_), b_(mo.get().b_), c_(mo.get().c_), d_(mo.get().d_), e_(mo.get().e_)
- #endif
{}
- #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
- EmplaceInt& operator=(EmplaceInt &&o)
- {
- #else
- EmplaceInt& operator=(detail::moved_object<EmplaceInt> mo)
+ EmplaceInt& operator=(BOOST_INTERPROCESS_RV_REF(EmplaceInt) o)
{
- EmplaceInt &o = mo.get();
- #endif
this->a_ = o.a_;
this->b_ = o.b_;
this->c_ = o.c_;
@@ -93,12 +84,6 @@
} //namespace test {
-template<>
-struct is_movable<test::EmplaceInt>
-{
- static const bool value = true;
-};
-
namespace test {
enum EmplaceOptions{
Modified: trunk/libs/interprocess/test/expand_bwd_test_allocator.hpp
==============================================================================
--- trunk/libs/interprocess/test/expand_bwd_test_allocator.hpp (original)
+++ trunk/libs/interprocess/test/expand_bwd_test_allocator.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,10 +19,10 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <memory>
#include <algorithm>
@@ -64,7 +64,7 @@
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef detail::version_type<expand_bwd_test_allocator, 2> version;
+ typedef boost::interprocess::version_type<expand_bwd_test_allocator, 2> version;
template<class T2>
struct rebind
@@ -118,14 +118,14 @@
//Experimental version 2 expand_bwd_test_allocator functions
std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
(void)preferred_size; (void)reuse; (void)command;
//This allocator only expands backwards!
- assert(m_allocations == 0 || (command & expand_bwd));
+ assert(m_allocations == 0 || (command & boost::interprocess::expand_bwd));
received_size = limit_size;
Modified: trunk/libs/interprocess/test/file_lock_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/file_lock_test.cpp (original)
+++ trunk/libs/interprocess/test/file_lock_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -11,12 +11,13 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/file_mapping.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "mutex_test_template.hpp"
#include "sharable_mutex_test_template.hpp"
#include "get_process_id_name.hpp"
#include <fstream>
-#include <cstdio>
+#include <cstdio> //std::remove
using namespace boost::interprocess;
//This wrapper is necessary to have a default constructor
@@ -49,16 +50,15 @@
{
scoped_lock<file_lock> sl(flock, test::delay(1));
}
- }/*
+ }
{
//Now test move semantics
file_lock mapping(test::get_process_id_name());
- file_lock move_ctor(detail::move_impl(mapping));
+ file_lock move_ctor(boost::interprocess::move(mapping));
file_lock move_assign;
- move_assign = detail::move_impl(move_ctor);
- mapping.swap(detail::move_impl(move_assign));
+ move_assign = boost::interprocess::move(move_ctor);
mapping.swap(move_assign);
- }*/
+ }
//test::test_all_lock<file_lock_lock_test_wrapper>();
//test::test_all_mutex<false, file_lock_lock_test_wrapper>();
Modified: trunk/libs/interprocess/test/file_mapping_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/file_mapping_test.cpp (original)
+++ trunk/libs/interprocess/test/file_mapping_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -16,12 +16,17 @@
#include <boost/interprocess/mapped_region.hpp>
#include <memory> //std::auto_ptr
#include <stdexcept> //std::exception
-#include <cstdio> //std::remove
#include <cstddef> //std::size_t
#include "get_process_id_name.hpp"
using namespace boost::interprocess;
+file_mapping get_file_mapping()
+{
+ file_mapping f;
+ return file_mapping(boost::interprocess::move(f));
+}
+
int main ()
{
try{
@@ -125,19 +130,19 @@
{
//Now test move semantics
file_mapping mapping(test::get_process_id_name(), read_only);
- file_mapping move_ctor(detail::move_impl(mapping));
+ file_mapping move_ctor(boost::interprocess::move(mapping));
file_mapping move_assign;
- move_assign = detail::move_impl(move_ctor);
- mapping.swap(detail::move_impl(move_assign));
+ move_assign = boost::interprocess::move(move_ctor);
mapping.swap(move_assign);
+ file_mapping ret(get_file_mapping());
}
}
catch(std::exception &exc){
- std::remove(test::get_process_id_name());
+ file_mapping::remove(test::get_process_id_name());
std::cout << "Unhandled exception: " << exc.what() << std::endl;
throw;
}
- std::remove(test::get_process_id_name());
+ file_mapping::remove(test::get_process_id_name());
return 0;
}
Modified: trunk/libs/interprocess/test/flat_tree_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/flat_tree_test.cpp (original)
+++ trunk/libs/interprocess/test/flat_tree_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -62,7 +62,7 @@
<char,
//simple_seq_fit<mutex_family>,
rbtree_best_fit<mutex_family>,
- flat_map_index
+ iset_index
> my_managed_shared_memory;
//Alias allocator type
@@ -132,10 +132,49 @@
{ return a.id_ < b.id_; }
};
+//Test recursive structures
+class recursive_flat_multiset
+{
+public:
+ int id_;
+ flat_multiset<recursive_flat_multiset> flat_set_;
+ friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_set &b)
+ { return a.id_ < b.id_; }
+};
+
+class recursive_flat_multimap
+{
+public:
+ int id_;
+ flat_map<recursive_flat_multimap, recursive_flat_multimap> map_;
+ friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b)
+ { return a.id_ < b.id_; }
+};
+
+template<class C>
+void test_move()
+{
+ //Now test move semantics
+ C original;
+ C move_ctor(boost::interprocess::move(original));
+ C move_assign;
+ move_assign = boost::interprocess::move(move_ctor);
+ move_assign.swap(original);
+}
+
int main()
{
using namespace boost::interprocess::test;
+ //Now test move semantics
+ {
+ test_move<flat_set<recursive_flat_set> >();
+ test_move<flat_multiset<recursive_flat_multiset> >();
+ test_move<flat_map<recursive_flat_map, recursive_flat_map> >();
+ test_move<flat_multimap<recursive_flat_multimap, recursive_flat_multimap> >();
+ }
+
+
if (0 != set_test<my_managed_shared_memory
,MyShmSet
,MyStdSet
@@ -207,7 +246,7 @@
return 1;
}
- #if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 3)
+ //#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 3)
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
@@ -219,8 +258,9 @@
return 1;
if(!boost::interprocess::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
return 1;
- #endif //!defined(__GNUC__)
+ //#endif //!defined(__GNUC__)
return 0;
+
}
#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/test/get_process_id_name.hpp
==============================================================================
--- trunk/libs/interprocess/test/get_process_id_name.hpp (original)
+++ trunk/libs/interprocess/test/get_process_id_name.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -23,8 +23,8 @@
inline void get_process_id_name(std::string &str)
{
std::stringstream sstr;
- sstr << "process_" << boost::interprocess::detail::get_current_process_id();
- str = sstr.str();
+ sstr << "process_" << boost::interprocess::detail::get_current_process_id() << std::ends;
+ str = sstr.str().c_str();
}
inline const char *get_process_id_name()
Modified: trunk/libs/interprocess/test/list_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/list_test.cpp (original)
+++ trunk/libs/interprocess/test/list_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -54,10 +54,9 @@
{
//Now test move semantics
list<recursive_list> original;
- list<recursive_list> move_ctor(detail::move_impl(original));
+ list<recursive_list> move_ctor(boost::interprocess::move(original));
list<recursive_list> move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
if(test::list_test<managed_shared_memory, MyList, true>())
Modified: trunk/libs/interprocess/test/list_test.hpp
==============================================================================
--- trunk/libs/interprocess/test/list_test.hpp (original)
+++ trunk/libs/interprocess/test/list_test.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,7 +19,6 @@
#include <functional>
#include "print_container.hpp"
#include <boost/interprocess/detail/move.hpp>
-#include <boost/interprocess/detail/move_iterator.hpp>
#include <string>
#include "get_process_id_name.hpp"
@@ -36,7 +35,7 @@
typedef typename MyShmList::value_type IntType;
for(int i = 0; i < max; ++i){
IntType move_me(i);
- shmlist->push_back(detail::move_impl(move_me));
+ shmlist->push_back(boost::interprocess::move(move_me));
stdlist->push_back(i);
}
if(!CheckEqualContainers(shmlist, stdlist))
@@ -54,7 +53,7 @@
typedef typename MyShmList::value_type IntType;
for(int i = 0; i < max; ++i){
IntType move_me(i);
- shmlist->push_front(detail::move_impl(move_me));
+ shmlist->push_front(boost::interprocess::move(move_me));
stdlist->push_front(i);
}
if(!CheckEqualContainers(shmlist, stdlist))
@@ -113,6 +112,7 @@
MyShmList *shmlist = segment.template construct<MyShmList>("MyList")
(segment.get_segment_manager());
+
MyStdList *stdlist = new MyStdList;
if(push_data_t::execute(max, shmlist, stdlist)){
@@ -135,14 +135,14 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
- shmlist->assign(detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(&aux_vect[50]));
+ shmlist->assign(boost::interprocess::make_move_iterator(&aux_vect[0])
+ ,boost::interprocess::make_move_iterator(&aux_vect[50]));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
@@ -165,15 +165,15 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmlist->insert(shmlist->begin()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(&aux_vect[50]));
+ ,boost::interprocess::make_move_iterator(&aux_vect[0])
+ ,boost::interprocess::make_move_iterator(&aux_vect[50]));
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
}
Modified: trunk/libs/interprocess/test/managed_mapped_file_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/managed_mapped_file_test.cpp (original)
+++ trunk/libs/interprocess/test/managed_mapped_file_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -31,7 +31,7 @@
{
//Remove the file it is already created
- std::remove(FileName);
+ file_mapping::remove(FileName);
const int max = 100;
void *array[max];
@@ -52,7 +52,7 @@
{
//Remove the file it is already created
- std::remove(FileName);
+ file_mapping::remove(FileName);
//Named allocate capable memory mapped file managed memory class
managed_mapped_file mfile(create_only, FileName, FileSize);
@@ -203,15 +203,14 @@
{
//Now test move semantics
managed_mapped_file original(open_only, FileName);
- managed_mapped_file move_ctor(detail::move_impl(original));
+ managed_mapped_file move_ctor(boost::interprocess::move(original));
managed_mapped_file move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
}
- std::remove(FileName);
+ file_mapping::remove(FileName);
return 0;
}
Modified: trunk/libs/interprocess/test/managed_shared_memory_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/managed_shared_memory_test.cpp (original)
+++ trunk/libs/interprocess/test/managed_shared_memory_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -199,10 +199,9 @@
{
//Now test move semantics
managed_shared_memory original(open_only, ShmemName);
- managed_shared_memory move_ctor(detail::move_impl(original));
+ managed_shared_memory move_ctor(boost::interprocess::move(original));
managed_shared_memory move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
}
Modified: trunk/libs/interprocess/test/managed_windows_shared_memory_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/managed_windows_shared_memory_test.cpp (original)
+++ trunk/libs/interprocess/test/managed_windows_shared_memory_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -9,8 +9,9 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
-#ifdef BOOST_WINDOWS
+#ifdef BOOST_INTERPROCESS_WINDOWS
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
@@ -130,9 +131,9 @@
//Now test move semantics
managed_windows_shared_memory original(open_only, MemName);
- managed_windows_shared_memory move_ctor(detail::move_impl(original));
+ managed_windows_shared_memory move_ctor(boost::interprocess::move(original));
managed_windows_shared_memory move_assign;
- move_assign = detail::move_impl(move_ctor);
+ move_assign = boost::interprocess::move(move_ctor);
}
}
Modified: trunk/libs/interprocess/test/map_test.hpp
==============================================================================
--- trunk/libs/interprocess/test/map_test.hpp (original)
+++ trunk/libs/interprocess/test/map_test.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,9 +17,8 @@
#include <functional>
#include <utility>
#include "print_container.hpp"
-#include <boost/interprocess/detail/move_iterator.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/iterators.hpp>
+#include <boost/interprocess/containers/pair.hpp>
#include <string>
#include "get_process_id_name.hpp"
@@ -41,7 +40,7 @@
int map_test ()
{
typedef typename MyShmMap::key_type IntType;
- typedef std::pair<IntType, IntType> IntPairType;
+ typedef boost::interprocess::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int memsize = 65536;
const char *const shMemName = test::get_process_id_name();
@@ -73,7 +72,9 @@
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect[i])IntPairType(IntType(i/2), IntType(i/2));
+ IntType i1(i/2);
+ IntType i2(i/2);
+ new(&aux_vect[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
typedef typename MyStdMap::value_type StdValueType;
@@ -86,21 +87,23 @@
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect3[i])IntPairType(IntType(i/2), IntType(i/2));
+ IntType i1(i/2);
+ IntType i2(i/2);
+ new(&aux_vect3[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
MyShmMap *shmmap2 =
segment.template construct<MyShmMap>("MyShmMap2")
- (detail::make_move_iterator(&aux_vect[0])
- , detail::make_move_iterator(aux_vect + 50)
+ (boost::interprocess::make_move_iterator(&aux_vect[0])
+ , boost::interprocess::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMap *stdmap2 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyShmMultiMap *shmmultimap2 =
segment.template construct<MyShmMultiMap>("MyShmMultiMap2")
- (detail::make_move_iterator(&aux_vect3[0])
- , detail::make_move_iterator(aux_vect3 + 50)
+ (boost::interprocess::make_move_iterator(&aux_vect3[0])
+ , boost::interprocess::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiMap *stdmultimap2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
@@ -112,71 +115,89 @@
delete stdmap2;
delete stdmultimap2;
}
+ {
+ //This is really nasty, but we have no other simple choice
+ IntPairType aux_vect[max];
+ for(int i = 0; i < max; ++i){
+ IntType i1(i);
+ IntType i2(i);
+ new(&aux_vect[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ IntPairType aux_vect3[max];
+ for(int i = 0; i < max; ++i){
+ IntType i1(i);
+ IntType i2(i);
+ new(&aux_vect3[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+
+ for(int i = 0; i < max; ++i){
+ shmmap->insert(boost::interprocess::move(aux_vect[i]));
+ stdmap->insert(StdPairType(i, i));
+ shmmultimap->insert(boost::interprocess::move(aux_vect3[i]));
+ stdmultimap->insert(StdPairType(i, i));
+ }
- int i, j;
- for(i = 0; i < max; ++i){
- shmmap->insert(detail::move_impl(IntPairType (detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmap->insert(StdPairType(i, i));
- shmmultimap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmultimap->insert(StdPairType(i, i));
- }
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
- if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+ typename MyShmMap::iterator it;
+ typename MyShmMap::const_iterator cit = it;
- typename MyShmMap::iterator it;
- typename MyShmMap::const_iterator cit = it;
+ shmmap->erase(shmmap->begin()++);
+ stdmap->erase(stdmap->begin()++);
+ shmmultimap->erase(shmmultimap->begin()++);
+ stdmultimap->erase(stdmultimap->begin()++);
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
- shmmap->erase(shmmap->begin()++);
- stdmap->erase(stdmap->begin()++);
- shmmultimap->erase(shmmultimap->begin()++);
- stdmultimap->erase(stdmultimap->begin()++);
- if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
-
- shmmap->erase(shmmap->begin());
- stdmap->erase(stdmap->begin());
- shmmultimap->erase(shmmultimap->begin());
- stdmultimap->erase(stdmultimap->begin());
- if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
-
- //Swapping test
- std::less<IntType> lessfunc;
- MyShmMap tmpshmemap2 (lessfunc, segment.get_segment_manager());
- MyStdMap tmpstdmap2;
- MyShmMultiMap tmpshmemultimap2(lessfunc, segment.get_segment_manager());
- MyStdMultiMap tmpstdmultimap2;
- shmmap->swap(tmpshmemap2);
- stdmap->swap(tmpstdmap2);
- shmmultimap->swap(tmpshmemultimap2);
- stdmultimap->swap(tmpstdmultimap2);
- shmmap->swap(tmpshmemap2);
- stdmap->swap(tmpstdmap2);
- shmmultimap->swap(tmpshmemultimap2);
- stdmultimap->swap(tmpstdmultimap2);
- if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+ shmmap->erase(shmmap->begin());
+ stdmap->erase(stdmap->begin());
+ shmmultimap->erase(shmmultimap->begin());
+ stdmultimap->erase(stdmultimap->begin());
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+ //Swapping test
+ std::less<IntType> lessfunc;
+ MyShmMap tmpshmemap2 (lessfunc, segment.get_segment_manager());
+ MyStdMap tmpstdmap2;
+ MyShmMultiMap tmpshmemultimap2(lessfunc, segment.get_segment_manager());
+ MyStdMultiMap tmpstdmultimap2;
+ shmmap->swap(tmpshmemap2);
+ stdmap->swap(tmpstdmap2);
+ shmmultimap->swap(tmpshmemultimap2);
+ stdmultimap->swap(tmpstdmultimap2);
+ shmmap->swap(tmpshmemap2);
+ stdmap->swap(tmpstdmap2);
+ shmmultimap->swap(tmpshmemultimap2);
+ stdmultimap->swap(tmpstdmultimap2);
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+ }
//Insertion from other container
//Initialize values
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1));
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1));
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect3[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
- shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
- StdPairType stdpairtype(-1, -1);
- constant_iterator<StdPairType> constant_beg(stdpairtype, 50), constant_end;
- stdmap->insert(constant_beg, constant_end);
- shmmultimap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
- stdmultimap->insert(constant_beg, constant_end);
+ shmmap->insert(boost::interprocess::make_move_iterator(&aux_vect[0]), boost::interprocess::make_move_iterator(aux_vect + 50));
+ shmmultimap->insert(boost::interprocess::make_move_iterator(&aux_vect3[0]), boost::interprocess::make_move_iterator(aux_vect3 + 50));
+ for(std::size_t i = 0; i != 50; ++i){
+ StdPairType stdpairtype(-1, -1);
+ stdmap->insert(stdpairtype);
+ stdmultimap->insert(stdpairtype);
+ }
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
@@ -192,34 +213,44 @@
{
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1));
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1));
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect3[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
IntPairType aux_vect4[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect4[i])IntPairType(IntType(-1), IntType(-1));
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect4[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
}
IntPairType aux_vect5[50];
for(int i = 0; i < 50; ++i){
- new(&aux_vect5[i])IntPairType(IntType(-1), IntType(-1));
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect5[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+
+ shmmap->insert(boost::interprocess::make_move_iterator(&aux_vect[0]), boost::interprocess::make_move_iterator(aux_vect + 50));
+ shmmap->insert(boost::interprocess::make_move_iterator(&aux_vect3[0]), boost::interprocess::make_move_iterator(aux_vect3 + 50));
+ shmmultimap->insert(boost::interprocess::make_move_iterator(&aux_vect4[0]), boost::interprocess::make_move_iterator(aux_vect4 + 50));
+ shmmultimap->insert(boost::interprocess::make_move_iterator(&aux_vect5[0]), boost::interprocess::make_move_iterator(aux_vect5 + 50));
+
+ for(std::size_t i = 0; i != 50; ++i){
+ StdPairType stdpairtype(-1, -1);
+ stdmap->insert(stdpairtype);
+ stdmultimap->insert(stdpairtype);
+ stdmap->insert(stdpairtype);
+ stdmultimap->insert(stdpairtype);
}
-
- shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
- shmmap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
- StdPairType stdpairtype(-1, -1);
- constant_iterator<StdPairType> constant_beg(stdpairtype, 50), constant_end;
- stdmap->insert(constant_beg, constant_end);
- stdmap->insert(constant_beg, constant_end);
- shmmultimap->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50));
- shmmultimap->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50));
- stdmultimap->insert(constant_beg, constant_end);
- stdmultimap->insert(constant_beg, constant_end);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
@@ -231,84 +262,158 @@
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
}
- for(i = 0; i < max; ++i){
- shmmap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmap->insert(StdPairType(i, i));
- shmmultimap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmultimap->insert(StdPairType(i, i));
- }
-
- if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
-
- for(i = 0; i < max; ++i){
- shmmap->insert(shmmap->begin(), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmap->insert(stdmap->begin(), StdPairType(i, i));
- //PrintContainers(shmmap, stdmap);
- shmmultimap->insert(shmmultimap->begin(), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i));
- //PrintContainers(shmmultimap, stdmultimap);
- if(!CheckEqualPairContainers(shmmap, stdmap))
- return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
- return 1;
-
- shmmap->insert(shmmap->end(), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmap->insert(stdmap->end(), StdPairType(i, i));
- shmmultimap->insert(shmmultimap->end(), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
- if(!CheckEqualPairContainers(shmmap, stdmap))
- return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
- return 1;
-
- shmmap->insert(shmmap->lower_bound(IntType(i)), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
- //PrintContainers(shmmap, stdmap);
- shmmultimap->insert(shmmultimap->lower_bound(IntType(i)), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
- //PrintContainers(shmmultimap, stdmultimap);
- if(!CheckEqualPairContainers(shmmap, stdmap))
- return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
- return 1;
- shmmap->insert(shmmap->upper_bound(IntType(i)), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
- //PrintContainers(shmmap, stdmap);
- shmmultimap->insert(shmmultimap->upper_bound(IntType(i)), detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
- //PrintContainers(shmmultimap, stdmultimap);
- if(!CheckEqualPairContainers(shmmap, stdmap))
- return 1;
- if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
- return 1;
- }
-
- //Compare count with std containers
- for(i = 0; i < max; ++i){
- if(shmmap->count(IntType(i)) != stdmap->count(i)){
- return -1;
+ {
+ //This is really nasty, but we have no other simple choice
+ IntPairType aux_vect[max];
+ for(int i = 0; i < max; ++i){
+ IntType i1(i);
+ IntType i2(i);
+ new(&aux_vect[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ IntPairType aux_vect3[max];
+ for(int i = 0; i < max; ++i){
+ IntType i1(i);
+ IntType i2(i);
+ new(&aux_vect3[i])IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+
+ for(int i = 0; i < max; ++i){
+ shmmap->insert(boost::interprocess::move(aux_vect[i]));
+ stdmap->insert(StdPairType(i, i));
+ shmmultimap->insert(boost::interprocess::move(aux_vect3[i]));
+ stdmultimap->insert(StdPairType(i, i));
}
- if(shmmultimap->count(IntType(i)) != stdmultimap->count(i)){
- return -1;
- }
- }
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
- //Now do count exercise
- shmmap->erase(shmmap->begin(), shmmap->end());
- shmmultimap->erase(shmmultimap->begin(), shmmultimap->end());
- shmmap->clear();
- shmmultimap->clear();
-
- for(j = 0; j < 3; ++j)
- for(i = 0; i < 100; ++i){
- shmmap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- shmmultimap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
- if(shmmap->count(IntType(i)) != typename MyShmMultiMap::size_type(1))
- return 1;
- if(shmmultimap->count(IntType(i)) != typename MyShmMultiMap::size_type(j+1))
- return 1;
+ for(int i = 0; i < max; ++i){
+ IntPairType intpair;
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmap->insert(shmmap->begin(), boost::interprocess::move(intpair));
+ stdmap->insert(stdmap->begin(), StdPairType(i, i));
+ //PrintContainers(shmmap, stdmap);
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmultimap->insert(shmmultimap->begin(), boost::interprocess::move(intpair));
+ stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i));
+ //PrintContainers(shmmultimap, stdmultimap);
+ if(!CheckEqualPairContainers(shmmap, stdmap))
+ return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
+ return 1;
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmap->insert(shmmap->end(), boost::interprocess::move(intpair));
+ stdmap->insert(stdmap->end(), StdPairType(i, i));
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmultimap->insert(shmmultimap->end(), boost::interprocess::move(intpair));
+ stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
+ if(!CheckEqualPairContainers(shmmap, stdmap))
+ return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
+ return 1;
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmap->insert(shmmap->lower_bound(IntType(i)), boost::interprocess::move(intpair));
+ stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
+ //PrintContainers(shmmap, stdmap);
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ {
+ IntType i1(i);
+ shmmultimap->insert(shmmultimap->lower_bound(boost::interprocess::move(i1)), boost::interprocess::move(intpair));
+ stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
+ }
+
+ //PrintContainers(shmmultimap, stdmultimap);
+ if(!CheckEqualPairContainers(shmmap, stdmap))
+ return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
+ return 1;
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ {
+ IntType i1(i);
+ shmmap->insert(shmmap->upper_bound(boost::interprocess::move(i1)), boost::interprocess::move(intpair));
+ stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
+ }
+ //PrintContainers(shmmap, stdmap);
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ {
+ IntType i1(i);
+ shmmultimap->insert(shmmultimap->upper_bound(boost::interprocess::move(i1)), boost::interprocess::move(intpair));
+ stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
+ }
+ //PrintContainers(shmmultimap, stdmultimap);
+ if(!CheckEqualPairContainers(shmmap, stdmap))
+ return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
+ return 1;
+ }
+
+ //Compare count with std containers
+ for(int i = 0; i < max; ++i){
+ if(shmmap->count(IntType(i)) != stdmap->count(i)){
+ return -1;
+ }
+
+ if(shmmultimap->count(IntType(i)) != stdmultimap->count(i)){
+ return -1;
+ }
+ }
+
+ //Now do count exercise
+ shmmap->erase(shmmap->begin(), shmmap->end());
+ shmmultimap->erase(shmmultimap->begin(), shmmultimap->end());
+ shmmap->clear();
+ shmmultimap->clear();
+
+ for(int j = 0; j < 3; ++j)
+ for(int i = 0; i < 100; ++i){
+ IntPairType intpair;
+ {
+ IntType i1(i), i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmap->insert(boost::interprocess::move(intpair));
+ {
+ IntType i1(i), i2(i);
+ new(&intpair)IntPairType(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ }
+ shmmultimap->insert(boost::interprocess::move(intpair));
+ if(shmmap->count(IntType(i)) != typename MyShmMultiMap::size_type(1))
+ return 1;
+ if(shmmultimap->count(IntType(i)) != typename MyShmMultiMap::size_type(j+1))
+ return 1;
+ }
}
segment.template destroy<MyShmMap>("MyShmMap");
@@ -337,7 +442,7 @@
int map_test_copyable ()
{
typedef typename MyShmMap::key_type IntType;
- typedef std::pair<IntType, IntType> IntPairType;
+ typedef boost::interprocess::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int memsize = 65536;
@@ -367,10 +472,18 @@
int i;
for(i = 0; i < max; ++i){
- shmmap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
+ {
+ IntType i1(i), i2(i);
+ IntPairType intpair1(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ shmmap->insert(boost::interprocess::move(intpair1));
stdmap->insert(StdPairType(i, i));
- shmmultimap->insert(detail::move_impl(IntPairType(detail::move_impl(IntType(i)), detail::move_impl(IntType(i)))));
+ }
+ {
+ IntType i1(i), i2(i);
+ IntPairType intpair2(boost::interprocess::move(i1), boost::interprocess::move(i2));
+ shmmultimap->insert(boost::interprocess::move(intpair2));
stdmultimap->insert(StdPairType(i, i));
+ }
}
if(!CheckEqualContainers(shmmap, stdmap)) return 1;
if(!CheckEqualContainers(shmmultimap, stdmultimap)) return 1;
Modified: trunk/libs/interprocess/test/mapped_file_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/mapped_file_test.cpp (original)
+++ trunk/libs/interprocess/test/mapped_file_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -12,6 +12,7 @@
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/detail/file_wrapper.hpp>
+#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include "named_creation_template.hpp"
#include <cstdio>
@@ -29,7 +30,7 @@
~file_destroyer()
{
//The last destructor will destroy the file
- std::remove(FileName);
+ file_mapping::remove(FileName);
}
};
@@ -60,7 +61,7 @@
{
typedef boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::detail::file_wrapper> mapped_file;
- std::remove(FileName);
+ file_mapping::remove(FileName);
test::test_named_creation<mapped_file_creation_test_wrapper>();
//Create and get name, size and address
@@ -76,11 +77,11 @@
std::memset(file1.get_user_address(), 0, file1.get_user_size());
//Now test move semantics
- mapped_file move_ctor(detail::move_impl(file1));
+ mapped_file move_ctor(boost::interprocess::move(file1));
mapped_file move_assign;
- move_assign = detail::move_impl(move_ctor);
+ move_assign = boost::interprocess::move(move_ctor);
}
- std::remove(FileName);
+ file_mapping::remove(FileName);
return 0;
}
Modified: trunk/libs/interprocess/test/memory_algorithm_test_template.hpp
==============================================================================
--- trunk/libs/interprocess/test/memory_algorithm_test_template.hpp (original)
+++ trunk/libs/interprocess/test/memory_algorithm_test_template.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,7 +17,7 @@
#include <new>
#include <utility>
#include <cstring> //std::memset
-#include <cstdio> //std::remove
+#include <boost/interprocess/containers/vector.hpp>
namespace boost { namespace interprocess { namespace test {
@@ -107,7 +107,7 @@
; ++i){
std::size_t received_size;
if(a.template allocation_command<char>
- ( shrink_in_place | nothrow_allocation, i*2
+ ( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, i*2
, i, received_size, static_cast<char*>(buffers[i])).first){
if(received_size > std::size_t(i*2)){
return false;
@@ -159,7 +159,7 @@
preferred_size = min_size > preferred_size ? min_size : preferred_size;
while(a.template allocation_command<char>
- ( expand_fwd | nothrow_allocation, min_size
+ ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
, preferred_size, received_size, static_cast<char*>(buffers[i])).first){
//Check received size is bigger than minimum
if(received_size < min_size){
@@ -197,10 +197,10 @@
for(int i = 0; true; ++i){
std::size_t received_size;
void *ptr = a.template allocation_command<char>
- ( allocate_new | nothrow_allocation, i, i*2, received_size).first;
+ ( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, i, i*2, received_size).first;
if(!ptr){
ptr = a.template allocation_command<char>
- ( allocate_new | nothrow_allocation, 1, i*2, received_size).first;
+ ( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, 1, i*2, received_size).first;
if(!ptr)
break;
}
@@ -214,7 +214,7 @@
; ++i){
std::size_t received_size;
if(a.template allocation_command<char>
- ( shrink_in_place | nothrow_allocation, received_sizes[i]
+ ( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_sizes[i]
, i, received_size, static_cast<char*>(buffers[i])).first){
if(received_size > std::size_t(received_sizes[i])){
return false;
@@ -233,7 +233,7 @@
std::size_t received_size;
std::size_t request_size = received_sizes[i];
if(a.template allocation_command<char>
- ( expand_fwd | nothrow_allocation, request_size
+ ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, request_size
, request_size, received_size, static_cast<char*>(buffers[i])).first){
if(received_size != received_sizes[i]){
return false;
@@ -298,7 +298,7 @@
preferred_size = min_size > preferred_size ? min_size : preferred_size;
while(a.template allocation_command<char>
- ( expand_fwd | nothrow_allocation, min_size
+ ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
, preferred_size, received_size, static_cast<char*>(buffers[i])).first){
//Check received size is bigger than minimum
if(received_size < min_size){
@@ -368,7 +368,7 @@
std::size_t min_size = (received_size + 1);
std::size_t prf_size = (received_size + (i+1)*2);
std::pair<void*, bool> ret = a.raw_allocation_command
- ( expand_bwd | nothrow_allocation, min_size
+ ( boost::interprocess::expand_bwd | boost::interprocess::nothrow_allocation, min_size
, prf_size, received_size, static_cast<char*>(ptr), sizeof_object);
if(!ret.first)
break;
@@ -631,7 +631,6 @@
template<class Allocator>
bool test_many_equal_allocation(Allocator &a)
{
- typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
for( deallocation_type t = DirectDeallocation
; t != EndDeallocationType
; t = (deallocation_type)((int)t + 1)){
@@ -665,16 +664,17 @@
if(!a.check_sanity())
return false;
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
std::vector<void*> buffers;
for(int i = 0; true; ++i){
- multiallocation_iterator it = a.allocate_many(i+1, (i+1)*2, std::nothrow);
- if(!it)
+ multiallocation_chain chain(a.allocate_many(i+1, (i+1)*2, std::nothrow));
+ if(chain.empty())
break;
- multiallocation_iterator itend;
- std::size_t n = 0;
- for(; it != itend; ++n){
- buffers.push_back(&*it++);
+ std::size_t n = chain.size();
+ while(!chain.empty()){
+ buffers.push_back(detail::get_pointer(chain.front()));
+ chain.pop_front();
}
if(n != std::size_t((i+1)*2))
return false;
@@ -740,7 +740,7 @@
template<class Allocator>
bool test_many_different_allocation(Allocator &a)
{
- typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
const std::size_t ArraySize = 11;
std::size_t requested_sizes[ArraySize];
for(std::size_t i = 0; i < ArraySize; ++i){
@@ -777,13 +777,13 @@
std::vector<void*> buffers;
for(int i = 0; true; ++i){
- multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
- if(!it)
+ multiallocation_chain chain(a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow));
+ if(chain.empty())
break;
- multiallocation_iterator itend;
- std::size_t n = 0;
- for(; it != itend; ++n){
- buffers.push_back(&*it++);
+ std::size_t n = chain.size();
+ while(!chain.empty()){
+ buffers.push_back(detail::get_pointer(chain.front()));
+ chain.pop_front();
}
if(n != ArraySize)
return false;
@@ -846,9 +846,9 @@
template<class Allocator>
bool test_many_deallocation(Allocator &a)
{
- typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
const std::size_t ArraySize = 11;
- std::vector<multiallocation_iterator> buffers;
+ vector<multiallocation_chain> buffers;
std::size_t requested_sizes[ArraySize];
for(std::size_t i = 0; i < ArraySize; ++i){
requested_sizes[i] = 4*i;
@@ -857,13 +857,13 @@
{
for(int i = 0; true; ++i){
- multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
- if(!it)
+ multiallocation_chain chain = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
+ if(chain.empty())
break;
- buffers.push_back(it);
+ buffers.push_back(boost::interprocess::move(chain));
}
for(int i = 0, max = (int)buffers.size(); i != max; ++i){
- a.deallocate_many(buffers[i]);
+ a.deallocate_many(boost::interprocess::move(buffers[i]));
}
buffers.clear();
bool ok = free_memory == a.get_free_memory() &&
@@ -873,13 +873,13 @@
{
for(int i = 0; true; ++i){
- multiallocation_iterator it = a.allocate_many(i*4, ArraySize, std::nothrow);
- if(!it)
+ multiallocation_chain chain(a.allocate_many(i*4, ArraySize, std::nothrow));
+ if(chain.empty())
break;
- buffers.push_back(it);
+ buffers.push_back(boost::interprocess::move(chain));
}
for(int i = 0, max = (int)buffers.size(); i != max; ++i){
- a.deallocate_many(buffers[i]);
+ a.deallocate_many(boost::interprocess::move(buffers[i]));
}
buffers.clear();
Modified: trunk/libs/interprocess/test/movable_int.hpp
==============================================================================
--- trunk/libs/interprocess/test/movable_int.hpp (original)
+++ trunk/libs/interprocess/test/movable_int.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -21,10 +21,11 @@
class movable_int
{
- movable_int(const movable_int&);
- movable_int &operator= (const movable_int&);
+ movable_int(movable_int&);
+ movable_int &operator= (movable_int&);
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(movable_int)
movable_int()
: m_int(0)
@@ -34,23 +35,12 @@
: m_int(a)
{}
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- movable_int(detail::moved_object<movable_int> mmi)
- : m_int(mmi.get().m_int)
- { mmi.get().m_int = 0; }
- #else
- movable_int(movable_int &&mmi)
+ movable_int(BOOST_INTERPROCESS_RV_REF(movable_int) mmi)
: m_int(mmi.m_int)
{ mmi.m_int = 0; }
- #endif
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- movable_int & operator= (detail::moved_object<movable_int> mmi)
- { this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; }
- #else
- movable_int & operator= (movable_int &&mmi)
+ movable_int & operator= (BOOST_INTERPROCESS_RV_REF(movable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
- #endif
movable_int & operator= (int i)
{ this->m_int = i; return *this; }
@@ -92,6 +82,7 @@
class movable_and_copyable_int
{
public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(movable_and_copyable_int)
movable_and_copyable_int()
: m_int(0)
@@ -108,23 +99,12 @@
movable_and_copyable_int &operator= (const movable_and_copyable_int& mi)
{ this->m_int = mi.m_int; return *this; }
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- movable_and_copyable_int(detail::moved_object<movable_and_copyable_int> mmi)
- : m_int(mmi.get().m_int)
- { mmi.get().m_int = 0; }
- #else
- movable_and_copyable_int(movable_and_copyable_int &&mmi)
+ movable_and_copyable_int(BOOST_INTERPROCESS_RV_REF(movable_and_copyable_int) mmi)
: m_int(mmi.m_int)
{ mmi.m_int = 0; }
- #endif
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- movable_and_copyable_int & operator= (detail::moved_object<movable_and_copyable_int> mmi)
- { this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; }
- #else
- movable_and_copyable_int & operator= (movable_and_copyable_int &&mmi)
+ movable_and_copyable_int & operator= (BOOST_INTERPROCESS_RV_REF(movable_and_copyable_int) mmi)
{ this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
- #endif
movable_and_copyable_int & operator= (int i)
{ this->m_int = i; return *this; }
@@ -167,26 +147,6 @@
} //namespace interprocess {
} //namespace boost {
-namespace boost{
-namespace interprocess{
-
-template<>
-struct is_movable<test::movable_int>
-{
- public:
- enum { value = true };
-};
-
-template<>
-struct is_movable<test::movable_and_copyable_int>
-{
- public:
- enum { value = true };
-};
-
-} //namespace interprocess{
-} //namespace boost{
-
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_TEST_MOVABLE_INT_HEADER
Modified: trunk/libs/interprocess/test/multi_index_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/multi_index_test.cpp (original)
+++ trunk/libs/interprocess/test/multi_index_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -28,8 +28,8 @@
using namespace boost::interprocess;
namespace bmi = boost::multi_index;
-typedef managed_shared_memory::allocator<char>::type char_allocator;
-typedef basic_string<char, std::char_traits<char>, char_allocator>shm_string;
+typedef managed_shared_memory::allocator<char>::type char_allocator;
+typedef basic_string<char, std::char_traits<char>, char_allocator> shm_string;
//Data to insert in shared memory
struct employee
@@ -75,19 +75,6 @@
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
adaptive_pool<employee,managed_shared_memory::segment_manager>
>;
-/*
-// Explicit instantiations to catch compile-time errors
-template class bmi::multi_index_container<
- employee,
- bmi::indexed_by<
- bmi::ordered_unique
- <bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
- bmi::ordered_non_unique<
- bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
- bmi::ordered_non_unique
- <bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
- cached_adaptive_pool<employee,managed_shared_memory::segment_manager>
->;
// Explicit instantiations to catch compile-time errors
template class bmi::multi_index_container<
@@ -99,48 +86,9 @@
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
- private_adaptive_pool<employee,managed_shared_memory::segment_manager>
->;
-*/
-// Explicit instantiations to catch compile-time errors
-template class bmi::multi_index_container<
- employee,
- bmi::indexed_by<
- bmi::ordered_unique
- <bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
- bmi::ordered_non_unique<
- bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
- bmi::ordered_non_unique
- <bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
node_allocator<employee,managed_shared_memory::segment_manager>
>;
-/*
-// Explicit instantiations to catch compile-time errors
-template class bmi::multi_index_container<
- employee,
- bmi::indexed_by<
- bmi::ordered_unique
- <bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
- bmi::ordered_non_unique<
- bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
- bmi::ordered_non_unique
- <bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
- cached_node_allocator<employee,managed_shared_memory::segment_manager>
->;
-// Explicit instantiations to catch compile-time errors
-template class bmi::multi_index_container<
- employee,
- bmi::indexed_by<
- bmi::ordered_unique
- <bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
- bmi::ordered_non_unique<
- bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
- bmi::ordered_non_unique
- <bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
- private_node_allocator<employee,managed_shared_memory::segment_manager>
->;
-*/
int main ()
{
return 0;
Modified: trunk/libs/interprocess/test/set_test.hpp
==============================================================================
--- trunk/libs/interprocess/test/set_test.hpp (original)
+++ trunk/libs/interprocess/test/set_test.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,7 +17,7 @@
#include <set>
#include <functional>
#include "print_container.hpp"
-#include <boost/interprocess/detail/move_iterator.hpp>
+#include <boost/interprocess/detail/move.hpp>
#include <string>
#include "get_process_id_name.hpp"
@@ -63,7 +63,7 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
@@ -72,21 +72,21 @@
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
- aux_vect3[i] = detail::move_impl(move_me);
+ aux_vect3[i] = boost::interprocess::move(move_me);
}
MyShmSet *shmset2 =
segment.template construct<MyShmSet>("MyShmSet2")
- (detail::make_move_iterator(&aux_vect[0])
- , detail::make_move_iterator(aux_vect + 50)
+ (boost::interprocess::make_move_iterator(&aux_vect[0])
+ , boost::interprocess::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyShmMultiSet *shmmultiset2 =
segment.template construct<MyShmMultiSet>("MyShmMultiSet2")
- (detail::make_move_iterator(&aux_vect3[0])
- , detail::make_move_iterator(aux_vect3 + 50)
+ (boost::interprocess::make_move_iterator(&aux_vect3[0])
+ , boost::interprocess::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
@@ -108,20 +108,20 @@
int i, j;
for(i = 0; i < max; ++i){
IntType move_me(i);
- shmset->insert(detail::move_impl(move_me));
+ shmset->insert(boost::interprocess::move(move_me));
stdset->insert(i);
IntType move_me2(i);
- shmmultiset->insert(detail::move_impl(move_me2));
+ shmmultiset->insert(boost::interprocess::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(detail::move_impl(move_me)" << std::endl;
+ std::cout << "Error in shmset->insert(boost::interprocess::move(move_me)" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(detail::move_impl(move_me)" << std::endl;
+ std::cout << "Error in shmmultiset->insert(boost::interprocess::move(move_me)" << std::endl;
return 1;
}
@@ -183,7 +183,7 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
@@ -192,19 +192,19 @@
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect3[i] = detail::move_impl(move_me);
+ aux_vect3[i] = boost::interprocess::move(move_me);
}
- shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
+ shmset->insert(boost::interprocess::make_move_iterator(&aux_vect[0]), boost::interprocess::make_move_iterator(aux_vect + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
- shmmultiset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
+ shmmultiset->insert(boost::interprocess::make_move_iterator(&aux_vect3[0]), boost::interprocess::make_move_iterator(aux_vect3 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(detail::make_move_iterator(&aux_vect[0])..." << std::endl;
+ std::cout << "Error in shmset->insert(boost::interprocess::make_move_iterator(&aux_vect[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(detail::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
+ std::cout << "Error in shmmultiset->insert(boost::interprocess::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
return 1;
}
@@ -228,7 +228,7 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect[i] = detail::move_impl(move_me);
+ aux_vect[i] = boost::interprocess::move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
@@ -237,35 +237,35 @@
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect3[i] = detail::move_impl(move_me);
+ aux_vect3[i] = boost::interprocess::move(move_me);
}
IntType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect4[i] = detail::move_impl(move_me);
+ aux_vect4[i] = boost::interprocess::move(move_me);
}
IntType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
- aux_vect5[i] = detail::move_impl(move_me);
+ aux_vect5[i] = boost::interprocess::move(move_me);
}
- shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
- shmset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
+ shmset->insert(boost::interprocess::make_move_iterator(&aux_vect[0]), boost::interprocess::make_move_iterator(aux_vect + 50));
+ shmset->insert(boost::interprocess::make_move_iterator(&aux_vect3[0]), boost::interprocess::make_move_iterator(aux_vect3 + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
stdset->insert(aux_vect2, aux_vect2 + 50);
- shmmultiset->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50));
- shmmultiset->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50));
+ shmmultiset->insert(boost::interprocess::make_move_iterator(&aux_vect4[0]), boost::interprocess::make_move_iterator(aux_vect4 + 50));
+ shmmultiset->insert(boost::interprocess::make_move_iterator(&aux_vect5[0]), boost::interprocess::make_move_iterator(aux_vect5 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(detail::make_move_iterator(&aux_vect3[0])..." << std::endl;
+ std::cout << "Error in shmset->insert(boost::interprocess::make_move_iterator(&aux_vect3[0])..." << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(detail::make_move_iterator(&aux_vect5[0])..." << std::endl;
+ std::cout << "Error in shmmultiset->insert(boost::interprocess::make_move_iterator(&aux_vect5[0])..." << std::endl;
return 1;
}
@@ -285,88 +285,88 @@
for(i = 0; i < max; ++i){
IntType move_me(i);
- shmset->insert(detail::move_impl(move_me));
+ shmset->insert(boost::interprocess::move(move_me));
stdset->insert(i);
IntType move_me2(i);
- shmmultiset->insert(detail::move_impl(move_me2));
+ shmmultiset->insert(boost::interprocess::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(detail::move_impl(move_me)) try 2" << std::endl;
+ std::cout << "Error in shmset->insert(boost::interprocess::move(move_me)) try 2" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(detail::move_impl(move_me2)) try 2" << std::endl;
+ std::cout << "Error in shmmultiset->insert(boost::interprocess::move(move_me2)) try 2" << std::endl;
return 1;
}
for(i = 0; i < max; ++i){
IntType move_me(i);
- shmset->insert(shmset->begin(), detail::move_impl(move_me));
+ shmset->insert(shmset->begin(), boost::interprocess::move(move_me));
stdset->insert(stdset->begin(), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
- shmmultiset->insert(shmmultiset->begin(), detail::move_impl(move_me2));
+ shmmultiset->insert(shmmultiset->begin(), boost::interprocess::move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(shmset->begin(), detail::move_impl(move_me))" << std::endl;
+ std::cout << "Error in shmset->insert(shmset->begin(), boost::interprocess::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(shmmultiset->begin(), detail::move_impl(move_me2))" << std::endl;
+ std::cout << "Error in shmmultiset->insert(shmmultiset->begin(), boost::interprocess::move(move_me2))" << std::endl;
return 1;
}
IntType move_me3(i);
- shmset->insert(shmset->end(), detail::move_impl(move_me3));
+ shmset->insert(shmset->end(), boost::interprocess::move(move_me3));
stdset->insert(stdset->end(), i);
IntType move_me4(i);
- shmmultiset->insert(shmmultiset->end(), detail::move_impl(move_me4));
+ shmmultiset->insert(shmmultiset->end(), boost::interprocess::move(move_me4));
stdmultiset->insert(stdmultiset->end(), i);
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(shmset->end(), detail::move_impl(move_me3))" << std::endl;
+ std::cout << "Error in shmset->insert(shmset->end(), boost::interprocess::move(move_me3))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(shmmultiset->end(), detail::move_impl(move_me4))" << std::endl;
+ std::cout << "Error in shmmultiset->insert(shmmultiset->end(), boost::interprocess::move(move_me4))" << std::endl;
return 1;
}
{
IntType move_me(i);
- shmset->insert(shmset->upper_bound(move_me), detail::move_impl(move_me));
+ shmset->insert(shmset->upper_bound(move_me), boost::interprocess::move(move_me));
stdset->insert(stdset->upper_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
- shmmultiset->insert(shmmultiset->upper_bound(move_me2), detail::move_impl(move_me2));
+ shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::interprocess::move(move_me2));
stdmultiset->insert(stdmultiset->upper_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(shmset->upper_bound(move_me), detail::move_impl(move_me))" << std::endl;
+ std::cout << "Error in shmset->insert(shmset->upper_bound(move_me), boost::interprocess::move(move_me))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(shmmultiset->upper_bound(move_me2), detail::move_impl(move_me2))" << std::endl;
+ std::cout << "Error in shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::interprocess::move(move_me2))" << std::endl;
return 1;
}
}
{
IntType move_me(i);
- shmset->insert(shmset->lower_bound(move_me), detail::move_impl(move_me2));
+ shmset->insert(shmset->lower_bound(move_me), boost::interprocess::move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
- shmmultiset->insert(shmmultiset->lower_bound(move_me2), detail::move_impl(move_me2));
+ shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::interprocess::move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset)){
- std::cout << "Error in shmset->insert(shmset->lower_bound(move_me), detail::move_impl(move_me2))" << std::endl;
+ std::cout << "Error in shmset->insert(shmset->lower_bound(move_me), boost::interprocess::move(move_me2))" << std::endl;
return 1;
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)){
- std::cout << "Error in shmmultiset->insert(shmmultiset->lower_bound(move_me2), detail::move_impl(move_me2))" << std::endl;
+ std::cout << "Error in shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::interprocess::move(move_me2))" << std::endl;
return 1;
}
}
@@ -392,9 +392,9 @@
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
IntType move_me(i);
- shmset->insert(detail::move_impl(move_me));
+ shmset->insert(boost::interprocess::move(move_me));
IntType move_me2(i);
- shmmultiset->insert(detail::move_impl(move_me2));
+ shmmultiset->insert(boost::interprocess::move(move_me2));
IntType count_me(i);
if(shmset->count(count_me) != typename MyShmMultiSet::size_type(1)){
std::cout << "Error in shmset->count(count_me)" << std::endl;
@@ -461,10 +461,10 @@
int i;
for(i = 0; i < max; ++i){
IntType move_me(i);
- shmset->insert(detail::move_impl(move_me));
+ shmset->insert(boost::interprocess::move(move_me));
stdset->insert(i);
IntType move_me2(i);
- shmmultiset->insert(detail::move_impl(move_me2));
+ shmmultiset->insert(boost::interprocess::move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
Modified: trunk/libs/interprocess/test/shared_memory_mapping_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/shared_memory_mapping_test.cpp (original)
+++ trunk/libs/interprocess/test/shared_memory_mapping_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -19,6 +19,12 @@
using namespace boost::interprocess;
+shared_memory_object get_shared_memory_mapping()
+{
+ shared_memory_object sh;
+ return shared_memory_object(boost::interprocess::move(sh));
+}
+
int main ()
{
try{
@@ -139,9 +145,10 @@
{
//Now test move semantics
shared_memory_object mapping(open_only, test::get_process_id_name(), read_write);
- shared_memory_object move_ctor(detail::move_impl(mapping));
+ shared_memory_object move_ctor(boost::interprocess::move(mapping));
shared_memory_object move_assign;
- move_assign = detail::move_impl(move_ctor);
+ move_assign = boost::interprocess::move(move_ctor);
+ shared_memory_object ret(get_shared_memory_mapping());
}
}
catch(std::exception &exc){
@@ -152,5 +159,3 @@
shared_memory_object::remove(test::get_process_id_name());
return 0;
}
-
-#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/test/shared_memory_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/shared_memory_test.cpp (original)
+++ trunk/libs/interprocess/test/shared_memory_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -31,13 +31,14 @@
}
};
+typedef detail::managed_open_or_create_impl<shared_memory_object> shared_memory;
+
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class shared_memory_creation_test_wrapper
: public eraser
- , public detail::managed_open_or_create_impl<shared_memory_object>
+ , public shared_memory
{
- typedef detail::managed_open_or_create_impl<shared_memory_object> shared_memory;
public:
shared_memory_creation_test_wrapper(create_only_t)
@@ -56,8 +57,6 @@
int main ()
{
- typedef detail::managed_open_or_create_impl<shared_memory_object> shared_memory;
-
try{
shared_memory_object::remove(ShmName);
test::test_named_creation<shared_memory_creation_test_wrapper>();
@@ -76,9 +75,9 @@
std::memset(shm1.get_user_address(), 0, shm1.get_user_size());
//Now test move semantics
- shared_memory move_ctor(detail::move_impl(shm1));
+ shared_memory move_ctor(boost::interprocess::move(shm1));
shared_memory move_assign;
- move_assign = detail::move_impl(move_ctor);
+ move_assign = boost::interprocess::move(move_ctor);
}
}
catch(std::exception &ex){
Modified: trunk/libs/interprocess/test/shared_ptr_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/shared_ptr_test.cpp (original)
+++ trunk/libs/interprocess/test/shared_ptr_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -25,6 +25,10 @@
#include <string>
#include "get_process_id_name.hpp"
+
+#include <boost/interprocess/sync/upgradable_lock.hpp>
+#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
+
using namespace boost::interprocess;
class base_class
@@ -613,7 +617,6 @@
shared_memory_object::remove(process_name.c_str());
}
-
int main()
{
if(0 != simple_test())
@@ -626,8 +629,7 @@
return 1;
test_alias();
-
- return 0;
}
#include <boost/interprocess/detail/config_end.hpp>
+
Modified: trunk/libs/interprocess/test/slist_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/slist_test.cpp (original)
+++ trunk/libs/interprocess/test/slist_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/slist.hpp>
@@ -54,10 +53,9 @@
{
//Now test move semantics
slist<recursive_slist> original;
- slist<recursive_slist> move_ctor(detail::move_impl(original));
+ slist<recursive_slist> move_ctor(boost::interprocess::move(original));
slist<recursive_slist> move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
@@ -79,8 +77,7 @@
if(!boost::interprocess::test::test_emplace
< slist<test::EmplaceInt>, Options>())
return 1;
-
- return 0;
}
#include <boost/interprocess/detail/config_end.hpp>
+
Added: trunk/libs/interprocess/test/stable_vector_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/interprocess/test/stable_vector_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -0,0 +1,90 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2007. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <algorithm>
+#include <memory>
+#include <vector>
+#include <iostream>
+#include <functional>
+
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/stable_vector.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include "allocator_v1.hpp"
+#include "check_equal_containers.hpp"
+#include "movable_int.hpp"
+#include "expand_bwd_test_allocator.hpp"
+#include "expand_bwd_test_template.hpp"
+#include "dummy_test_allocator.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//Explicit instantiation to detect compilation errors
+//template class stable_vector<test::movable_and_copyable_int,
+ //test::dummy_test_allocator<test::movable_and_copyable_int> >;
+
+class recursive_vector
+{
+ public:
+ int id_;
+ stable_vector<recursive_vector> vector_;
+};
+
+void recursive_vector_test()//Test for recursive types
+{
+ stable_vector<recursive_vector> recursive_vector_vector;
+}
+
+int main()
+{
+ recursive_vector_test();
+ {
+ //Now test move semantics
+ stable_vector<recursive_vector> original;
+ stable_vector<recursive_vector> move_ctor(boost::interprocess::move(original));
+ stable_vector<recursive_vector> move_assign;
+ move_assign = boost::interprocess::move(move_ctor);
+ move_assign.swap(original);
+ }
+ typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
+ typedef stable_vector<int, ShmemAllocator> MyVector;
+
+ typedef test::allocator_v1<int, managed_shared_memory::segment_manager> ShmemV1Allocator;
+ typedef stable_vector<int, ShmemV1Allocator> MyV1Vector;
+
+ typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
+ typedef stable_vector<test::movable_int, ShmemMoveAllocator> MyMoveVector;
+
+ typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
+ typedef stable_vector<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveVector;
+
+ if(test::vector_test<managed_shared_memory, MyVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyV1Vector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyMoveVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyCopyMoveVector>())
+ return 1;
+
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
+ if(!boost::interprocess::test::test_emplace
+ < stable_vector<test::EmplaceInt>, Options>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/interprocess/test/string_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/string_test.cpp (original)
+++ trunk/libs/interprocess/test/string_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -127,7 +127,7 @@
std::sprintf(buffer, "%i", i);
auxShmString += buffer;
auxStdString += buffer;
- shmStringVect->push_back(detail::move_impl(auxShmString));
+ shmStringVect->push_back(boost::interprocess::move(auxShmString));
stdStringVect->push_back(auxStdString);
}
@@ -157,7 +157,7 @@
std::sprintf(buffer, "%i", i);
auxShmString += buffer;
auxStdString += buffer;
- shmStringVect->insert(shmStringVect->begin(), detail::move_impl(auxShmString));
+ shmStringVect->insert(shmStringVect->begin(), boost::interprocess::move(auxShmString));
stdStringVect->insert(stdStringVect->begin(), auxStdString);
}
Modified: trunk/libs/interprocess/test/tree_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/tree_test.cpp (original)
+++ trunk/libs/interprocess/test/tree_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#include <boost/interprocess/detail/config_begin.hpp>
#include <set>
#include <boost/interprocess/managed_shared_memory.hpp>
@@ -33,32 +32,7 @@
///////////////////////////////////////////////////////////////////
using namespace boost::interprocess;
-/*
-//Explicit instantiation to detect compilation errors
-template class boost::interprocess::set
- <test::movable_and_copyable_int
- ,std::less<test::movable_and_copyable_int>
- ,test::dummy_test_allocator<test::movable_and_copyable_int> >;
-
-template class boost::interprocess::map
- <test::movable_and_copyable_int
- ,test::movable_and_copyable_int
- ,std::less<test::movable_and_copyable_int>
- ,test::dummy_test_allocator<std::pair<const test::movable_and_copyable_int
- ,test::movable_and_copyable_int> > >;
-
-template class boost::interprocess::multiset
- <test::movable_and_copyable_int
- ,std::less<test::movable_and_copyable_int>
- ,test::dummy_test_allocator<test::movable_and_copyable_int> >;
-
-template class boost::interprocess::multimap
- <test::movable_and_copyable_int
- ,test::movable_and_copyable_int
- ,std::less<test::movable_and_copyable_int>
- ,test::dummy_test_allocator<std::pair<const test::movable_and_copyable_int
- ,test::movable_and_copyable_int> > >;
-*/
+
//Customize managed_shared_memory class
typedef basic_managed_shared_memory
<char,
@@ -159,14 +133,13 @@
};
template<class C>
-void test_move_semantics()
+void test_move()
{
//Now test move semantics
C original;
- C move_ctor(detail::move_impl(original));
+ C move_ctor(boost::interprocess::move(original));
C move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
@@ -181,10 +154,10 @@
}
//Now test move semantics
{
- test_move_semantics<set<recursive_set> >();
- test_move_semantics<multiset<recursive_multiset> >();
- test_move_semantics<map<recursive_map, recursive_map> >();
- test_move_semantics<multimap<recursive_multimap, recursive_multimap> >();
+ test_move<set<recursive_set> >();
+ test_move<multiset<recursive_multiset> >();
+ test_move<map<recursive_map, recursive_map> >();
+ test_move<multimap<recursive_multimap, recursive_multimap> >();
}
using namespace boost::interprocess::detail;
@@ -221,6 +194,7 @@
return 1;
}
+
if (0 != test::map_test<my_managed_shared_memory
,MyShmMap
,MyStdMap
@@ -263,6 +237,7 @@
return 1;
if(!boost::interprocess::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
+
return 0;
}
Modified: trunk/libs/interprocess/test/unique_ptr_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/unique_ptr_test.cpp (original)
+++ trunk/libs/interprocess/test/unique_ptr_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -70,14 +70,14 @@
//Test some copy constructors
my_unique_ptr_class my_ptr3(0, segment.get_deleter<MyClass>());
- my_unique_ptr_class my_ptr4(detail::move_impl(my_ptr3));
+ my_unique_ptr_class my_ptr4(boost::interprocess::move(my_ptr3));
//Construct a list and fill
MyList list(segment.get_segment_manager());
//Insert from my_unique_ptr_class
- list.push_front(detail::move_impl(my_ptr));
- list.push_back(detail::move_impl(my_ptr2));
+ list.push_front(boost::interprocess::move(my_ptr));
+ list.push_back(boost::interprocess::move(my_ptr2));
//Check pointers
assert(my_ptr.get() == 0);
@@ -85,20 +85,13 @@
assert(list.begin()->get() == ptr1);
assert(list.rbegin()->get() == ptr2);
- //MyList list2(detail::move_impl(list));
- //list2.swap(detail::move_impl(MyList(segment.get_segment_manager())));
- //list.swap(detail::move_impl(MyList(segment.get_segment_manager())));
-
- assert(list.begin()->get() == ptr1);
- assert(list.rbegin()->get() == ptr2);
-
//Construct a set and fill
typedef std::less<my_unique_ptr_class> set_less_t;
MySet set(set_less_t(), segment.get_segment_manager());
//Insert in set from list passing ownership
- set.insert(detail::move_impl(*list.begin()));
- set.insert(detail::move_impl(*list.rbegin()));
+ set.insert(boost::interprocess::move(*list.begin()));
+ set.insert(boost::interprocess::move(*list.rbegin()));
//Check pointers
assert(list.begin()->get() == 0);
@@ -120,12 +113,12 @@
//Insert from my_unique_ptr_class
if(ptr1 < ptr2){
- vector.insert(vector.begin(), detail::move_impl(*set.begin()));
- vector.insert(vector.end(), detail::move_impl(*set.rbegin()));
+ vector.insert(vector.begin(), boost::interprocess::move(*set.begin()));
+ vector.insert(vector.end(), boost::interprocess::move(*set.rbegin()));
}
else{
- vector.insert(vector.begin(), detail::move_impl(*set.rbegin()));
- vector.insert(vector.end(), detail::move_impl(*set.begin()));
+ vector.insert(vector.begin(), boost::interprocess::move(*set.rbegin()));
+ vector.insert(vector.end(), boost::interprocess::move(*set.begin()));
}
//Check pointers
@@ -134,14 +127,14 @@
assert(vector.begin()->get() == ptr1);
assert(vector.rbegin()->get() == ptr2);
- MyVector vector2(detail::move_impl(vector));
+ MyVector vector2(boost::interprocess::move(vector));
vector2.swap(vector);
assert(vector.begin()->get() == ptr1);
assert(vector.rbegin()->get() == ptr2);
my_unique_ptr_class a(0, segment.get_deleter<MyClass>()), b(0, segment.get_deleter<MyClass>());
- a = detail::move_impl(b);
+ a = boost::interprocess::move(b);
}
shared_memory_object::remove(process_name.c_str());
return 0;
Modified: trunk/libs/interprocess/test/upgradable_mutex_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/upgradable_mutex_test.cpp (original)
+++ trunk/libs/interprocess/test/upgradable_mutex_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -35,135 +35,135 @@
//Conversions to scoped_lock
{
scoped_lock<Mutex> lock(mut);
- scoped_lock<Mutex> e_lock(detail::move_impl(lock));
- lock.swap(detail::move_impl(e_lock));
+ scoped_lock<Mutex> e_lock(boost::interprocess::move(lock));
+ lock.swap(e_lock);
}
{
scoped_lock<Mutex> lock(mut);
scoped_lock<Mutex> e_lock(mut2);
- e_lock = detail::move_impl(lock);
+ e_lock = boost::interprocess::move(lock);
}
{
upgradable_lock<Mutex> u_lock(mut);
//This calls unlock_upgradable_and_lock()
- scoped_lock<Mutex> e_lock(detail::move_impl(u_lock));
+ scoped_lock<Mutex> e_lock(boost::interprocess::move(u_lock));
}
{
upgradable_lock<Mutex> u_lock(mut);
//This calls unlock_upgradable_and_lock()
scoped_lock<Mutex> e_lock(mut2);
- scoped_lock<Mutex> moved(detail::move_impl(u_lock));
- e_lock = detail::move_impl(moved);
+ scoped_lock<Mutex> moved(boost::interprocess::move(u_lock));
+ e_lock = boost::interprocess::move(moved);
}
{
upgradable_lock<Mutex> u_lock(mut);
//This calls try_unlock_upgradable_and_lock()
- scoped_lock<Mutex> e_lock(detail::move_impl(u_lock), try_to_lock);
+ scoped_lock<Mutex> e_lock(boost::interprocess::move(u_lock), try_to_lock);
}
{
upgradable_lock<Mutex> u_lock(mut);
//This calls try_unlock_upgradable_and_lock()
scoped_lock<Mutex> e_lock(mut2);
- scoped_lock<Mutex> moved(detail::move_impl(u_lock), try_to_lock);
- e_lock = detail::move_impl(moved);
+ scoped_lock<Mutex> moved(boost::interprocess::move(u_lock), try_to_lock);
+ e_lock = boost::interprocess::move(moved);
}
{
boost::posix_time::ptime t = test::delay(100);
upgradable_lock<Mutex> u_lock(mut);
//This calls timed_unlock_upgradable_and_lock()
- scoped_lock<Mutex> e_lock(detail::move_impl(u_lock), t);
+ scoped_lock<Mutex> e_lock(boost::interprocess::move(u_lock), t);
}
{
boost::posix_time::ptime t = test::delay(100);
upgradable_lock<Mutex> u_lock(mut);
//This calls timed_unlock_upgradable_and_lock()
scoped_lock<Mutex> e_lock(mut2);
- scoped_lock<Mutex> moved(detail::move_impl(u_lock), t);
- e_lock = detail::move_impl(moved);
+ scoped_lock<Mutex> moved(boost::interprocess::move(u_lock), t);
+ e_lock = boost::interprocess::move(moved);
}
{
sharable_lock<Mutex> s_lock(mut);
//This calls try_unlock_sharable_and_lock()
- scoped_lock<Mutex> e_lock(detail::move_impl(s_lock), try_to_lock);
+ scoped_lock<Mutex> e_lock(boost::interprocess::move(s_lock), try_to_lock);
}
{
sharable_lock<Mutex> s_lock(mut);
//This calls try_unlock_sharable_and_lock()
scoped_lock<Mutex> e_lock(mut2);
- scoped_lock<Mutex> moved(detail::move_impl(s_lock), try_to_lock);
- e_lock = detail::move_impl(moved);
+ scoped_lock<Mutex> moved(boost::interprocess::move(s_lock), try_to_lock);
+ e_lock = boost::interprocess::move(moved);
}
//Conversions to upgradable_lock
{
upgradable_lock<Mutex> lock(mut);
- upgradable_lock<Mutex> u_lock(detail::move_impl(lock));
- lock.swap(detail::move_impl(u_lock));
+ upgradable_lock<Mutex> u_lock(boost::interprocess::move(lock));
+ lock.swap(u_lock);
}
{
upgradable_lock<Mutex> lock(mut);
upgradable_lock<Mutex> u_lock(mut2);
- upgradable_lock<Mutex> moved(detail::move_impl(lock));
- u_lock = detail::move_impl(moved);
+ upgradable_lock<Mutex> moved(boost::interprocess::move(lock));
+ u_lock = boost::interprocess::move(moved);
}
{
sharable_lock<Mutex> s_lock(mut);
//This calls unlock_sharable_and_lock_upgradable()
- upgradable_lock<Mutex> u_lock(detail::move_impl(s_lock), try_to_lock);
+ upgradable_lock<Mutex> u_lock(boost::interprocess::move(s_lock), try_to_lock);
}
{
sharable_lock<Mutex> s_lock(mut);
//This calls unlock_sharable_and_lock_upgradable()
upgradable_lock<Mutex> u_lock(mut2);
- upgradable_lock<Mutex> moved(detail::move_impl(s_lock), try_to_lock);
- u_lock = detail::move_impl(moved);
+ upgradable_lock<Mutex> moved(boost::interprocess::move(s_lock), try_to_lock);
+ u_lock = boost::interprocess::move(moved);
}
{
scoped_lock<Mutex> e_lock(mut);
//This calls unlock_and_lock_upgradable()
- upgradable_lock<Mutex> u_lock(detail::move_impl(e_lock));
+ upgradable_lock<Mutex> u_lock(boost::interprocess::move(e_lock));
}
{
scoped_lock<Mutex> e_lock(mut);
//This calls unlock_and_lock_upgradable()
upgradable_lock<Mutex> u_lock(mut2);
- upgradable_lock<Mutex> moved(detail::move_impl(e_lock));
- u_lock = detail::move_impl(moved);
+ upgradable_lock<Mutex> moved(boost::interprocess::move(e_lock));
+ u_lock = boost::interprocess::move(moved);
}
//Conversions to sharable_lock
{
sharable_lock<Mutex> lock(mut);
- sharable_lock<Mutex> s_lock(detail::move_impl(lock));
- lock.swap(detail::move_impl(s_lock));
+ sharable_lock<Mutex> s_lock(boost::interprocess::move(lock));
+ lock.swap(s_lock);
}
{
sharable_lock<Mutex> lock(mut);
sharable_lock<Mutex> s_lock(mut2);
- sharable_lock<Mutex> moved(detail::move_impl(lock));
- s_lock = detail::move_impl(moved);
+ sharable_lock<Mutex> moved(boost::interprocess::move(lock));
+ s_lock = boost::interprocess::move(moved);
}
{
upgradable_lock<Mutex> u_lock(mut);
//This calls unlock_upgradable_and_lock_sharable()
- sharable_lock<Mutex> s_lock(detail::move_impl(u_lock));
+ sharable_lock<Mutex> s_lock(boost::interprocess::move(u_lock));
}
{
upgradable_lock<Mutex> u_lock(mut);
//This calls unlock_upgradable_and_lock_sharable()
sharable_lock<Mutex> s_lock(mut2);
- sharable_lock<Mutex> moved(detail::move_impl(u_lock));
- s_lock = detail::move_impl(moved);
+ sharable_lock<Mutex> moved(boost::interprocess::move(u_lock));
+ s_lock = boost::interprocess::move(moved);
}
{
scoped_lock<Mutex> e_lock(mut);
//This calls unlock_and_lock_sharable()
- sharable_lock<Mutex> s_lock(detail::move_impl(e_lock));
+ sharable_lock<Mutex> s_lock(boost::interprocess::move(e_lock));
}
{
scoped_lock<Mutex> e_lock(mut);
//This calls unlock_and_lock_sharable()
sharable_lock<Mutex> s_lock(mut2);
- sharable_lock<Mutex> moved(detail::move_impl(e_lock));
- s_lock = detail::move_impl(moved);
+ sharable_lock<Mutex> moved(boost::interprocess::move(e_lock));
+ s_lock = boost::interprocess::move(moved);
}
}
Modified: trunk/libs/interprocess/test/user_buffer_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/user_buffer_test.cpp (original)
+++ trunk/libs/interprocess/test/user_buffer_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -59,19 +59,17 @@
{
//Now test move semantics
managed_heap_memory original(memsize);
- managed_heap_memory move_ctor(detail::move_impl(original));
+ managed_heap_memory move_ctor(boost::interprocess::move(original));
managed_heap_memory move_assign;
- move_assign = detail::move_impl(move_ctor);
- original.swap(detail::move_impl(move_assign));
+ move_assign = boost::interprocess::move(move_ctor);
original.swap(move_assign);
}
{
//Now test move semantics
managed_external_buffer original(create_only, static_buffer, memsize);
- managed_external_buffer move_ctor(detail::move_impl(original));
+ managed_external_buffer move_ctor(boost::interprocess::move(original));
managed_external_buffer move_assign;
- move_assign = detail::move_impl(move_ctor);
- original.swap(detail::move_impl(move_assign));
+ move_assign = boost::interprocess::move(move_ctor);
original.swap(move_assign);
}
@@ -84,13 +82,13 @@
//Test move semantics
{
wmanaged_external_buffer user_default;
- wmanaged_external_buffer temp_external(detail::move_impl(user_buffer));
- user_default = detail::move_impl(temp_external);
- user_buffer = detail::move_impl(user_default);
+ wmanaged_external_buffer temp_external(boost::interprocess::move(user_buffer));
+ user_default = boost::interprocess::move(temp_external);
+ user_buffer = boost::interprocess::move(user_default);
wmanaged_heap_memory heap_default;
- wmanaged_heap_memory temp_heap(detail::move_impl(heap_buffer));
- heap_default = detail::move_impl(temp_heap);
- heap_buffer = detail::move_impl(heap_default);
+ wmanaged_heap_memory temp_heap(boost::interprocess::move(heap_buffer));
+ heap_default = boost::interprocess::move(temp_heap);
+ heap_buffer = boost::interprocess::move(heap_default);
}
//Initialize memory
Modified: trunk/libs/interprocess/test/vector_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/vector_test.cpp (original)
+++ trunk/libs/interprocess/test/vector_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -44,16 +44,7 @@
if(!test::test_all_expand_bwd<int_vector>())
return 1;
-/*
- //First raw volatile ints
- typedef test::expand_bwd_test_allocator<volatile int>
- volatile_int_allocator_type;
- typedef vector<volatile int, volatile_int_allocator_type>
- volatile_int_vector;
- if(!test::test_all_expand_bwd<volatile_int_vector>())
- return 1;
-*/
//Now user defined wrapped int
typedef test::expand_bwd_test_allocator<test::int_holder>
int_holder_allocator_type;
@@ -94,17 +85,16 @@
{
//Now test move semantics
vector<recursive_vector> original;
- vector<recursive_vector> move_ctor(detail::move_impl(original));
+ vector<recursive_vector> move_ctor(boost::interprocess::move(original));
vector<recursive_vector> move_assign;
- move_assign = detail::move_impl(move_ctor);
- move_assign.swap(detail::move_impl(original));
+ move_assign = boost::interprocess::move(move_ctor);
move_assign.swap(original);
}
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
typedef vector<int, ShmemAllocator> MyVector;
- //typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
- //typedef vector<volatile int, ShmemVolatileAllocator> MyVolatileVector;
+ typedef test::allocator_v1<int, managed_shared_memory::segment_manager> ShmemV1Allocator;
+ typedef vector<int, ShmemV1Allocator> MyV1Vector;
typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
typedef vector<test::movable_int, ShmemMoveAllocator> MyMoveVector;
@@ -115,8 +105,8 @@
if(test::vector_test<managed_shared_memory, MyVector>())
return 1;
- //if(test::vector_test<managed_shared_memory, MyVolatileVector>())
- //return 1;
+ if(test::vector_test<managed_shared_memory, MyV1Vector>())
+ return 1;
if(test::vector_test<managed_shared_memory, MyMoveVector>())
return 1;
Modified: trunk/libs/interprocess/test/vector_test.hpp
==============================================================================
--- trunk/libs/interprocess/test/vector_test.hpp (original)
+++ trunk/libs/interprocess/test/vector_test.hpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -17,8 +17,8 @@
#include <list>
#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/move_iterator.hpp>
#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
@@ -32,14 +32,14 @@
namespace test{
template<class V1, class V2>
-bool copyable_only(V1 *, V2 *, detail::false_type)
+bool copyable_only(V1 *, V2 *, boost::interprocess::detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
-bool copyable_only(V1 *shmvector, V2 *stdvector, detail::true_type)
+bool copyable_only(V1 *shmvector, V2 *stdvector, boost::interprocess::detail::true_type)
{
typedef typename V1::value_type IntType;
std::size_t size = shmvector->size();
@@ -50,18 +50,18 @@
{
IntType move_me(1);
stdvector->insert(stdvector->begin()+size/2, 50, 1);
- shmvector->insert(shmvector->begin()+size/2, 50, detail::move_impl(move_me));
+ shmvector->insert(shmvector->begin()+size/2, 50, boost::interprocess::move(move_me));
if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
}
{
IntType move_me(2);
- shmvector->assign(shmvector->size()/2, detail::move_impl(move_me));
+ shmvector->assign(shmvector->size()/2, boost::interprocess::move(move_me));
stdvector->assign(stdvector->size()/2, 2);
if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
}
{
IntType move_me(3);
- shmvector->assign(shmvector->size()*3-1, detail::move_impl(move_me));
+ shmvector->assign(shmvector->size()*3-1, boost::interprocess::move(move_me));
stdvector->assign(stdvector->size()*3-1, 3);
if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
}
@@ -111,8 +111,9 @@
for(int i = 0; i < max; ++i){
IntType new_int(i);
- shmvector->insert(shmvector->end(), detail::move_impl(new_int));
+ shmvector->insert(shmvector->end(), boost::interprocess::move(new_int));
stdvector->insert(stdvector->end(), i);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
}
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
@@ -133,7 +134,8 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
- aux_vect[i] = detail::move_impl(new_int);
+ BOOST_STATIC_ASSERT((boost::interprocess::is_movable<boost::interprocess::test::movable_int>::value == true));
+ aux_vect[i] = boost::interprocess::move(new_int);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
@@ -141,8 +143,8 @@
}
shmvector->insert(shmvector->end()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(aux_vect + 50));
+ ,boost::interprocess::make_move_iterator(&aux_vect[0])
+ ,boost::interprocess::make_move_iterator(aux_vect + 50));
stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
@@ -156,15 +158,15 @@
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType new_int(-1);
- aux_vect[i] = detail::move_impl(new_int);
+ aux_vect[i] = boost::interprocess::move(new_int);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmvector->insert(shmvector->begin()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(aux_vect + 50));
+ ,boost::interprocess::make_move_iterator(&aux_vect[0])
+ ,boost::interprocess::make_move_iterator(aux_vect + 50));
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
}
@@ -174,7 +176,7 @@
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
IntType push_back_this(1);
- shmvector->push_back(detail::move_impl(push_back_this));
+ shmvector->push_back(boost::interprocess::move(push_back_this));
stdvector->push_back(int(1));
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
@@ -189,7 +191,7 @@
for(int i = 0; i < max; ++i){
IntType insert_this(i);
- shmvector->insert(shmvector->begin(), detail::move_impl(insert_this));
+ shmvector->insert(shmvector->begin(), boost::interprocess::move(insert_this));
stdvector->insert(stdvector->begin(), i);
}
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
@@ -204,6 +206,18 @@
stdvector->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
}
+/*
+ std::size_t cap = shmvector->capacity();
+ shmvector->reserve(cap*2);
+ stdvector->reserve(cap*2);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ shmvector->resize(0);
+ stdvector->resize(0);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ shmvector->resize(cap*2);
+ stdvector->resize(cap*2);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+*/
delete stdvector;
segment.template destroy<MyShmVector>("MyShmVector");
Modified: trunk/libs/interprocess/test/windows_shared_memory_mapping_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/windows_shared_memory_mapping_test.cpp (original)
+++ trunk/libs/interprocess/test/windows_shared_memory_mapping_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -10,7 +10,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
-#ifdef BOOST_WINDOWS
+#ifdef BOOST_INTERPROCESS_WINDOWS
#include <fstream>
#include <iostream>
Modified: trunk/libs/interprocess/test/windows_shared_memory_test.cpp
==============================================================================
--- trunk/libs/interprocess/test/windows_shared_memory_test.cpp (original)
+++ trunk/libs/interprocess/test/windows_shared_memory_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -11,7 +11,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#ifdef BOOST_WINDOWS
+#ifdef BOOST_INTERPROCESS_WINDOWS
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
@@ -32,16 +32,14 @@
}
static const std::size_t ShmSize = 1000;
+typedef detail::managed_open_or_create_impl
+ <windows_shared_memory, false> windows_shared_memory_t;
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class shared_memory_creation_test_wrapper
- : public detail::managed_open_or_create_impl
- <windows_shared_memory, false>
+ : public windows_shared_memory_t
{
- typedef detail::managed_open_or_create_impl
- <windows_shared_memory, false> windows_shared_memory_t;
-
public:
shared_memory_creation_test_wrapper(create_only_t)
: windows_shared_memory_t(create_only, name_initialization_routine(), ShmSize)
@@ -59,8 +57,6 @@
int main ()
{
- typedef detail::managed_open_or_create_impl<windows_shared_memory, false> windows_shared_memory_t;
-
try{
test::test_named_creation<shared_memory_creation_test_wrapper>();
}
@@ -79,6 +75,6 @@
return 0;
}
-#endif //#ifdef BOOST_WINDOWS
+#endif //#ifdef BOOST_INTERPROCESS_WINDOWS
#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/libs/intrusive/doc/intrusive.qbk
==============================================================================
--- trunk/libs/intrusive/doc/intrusive.qbk (original)
+++ trunk/libs/intrusive/doc/intrusive.qbk 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -1280,7 +1280,9 @@
provides a bucket length that is not power of two.
Default: `power_2_buckets<false>`.
-* [*`cache_begin<bool Enabled>`]: Due to its internal structure, finding the first
+* [*`cache_begin<bool Enabled>`]:
+ [*Note: this option is not compatible with `auto_unlink` hooks].
+ Due to its internal structure, finding the first
element of an unordered container (`begin()` operation) is
amortized constant-time. It's possible to speed up `begin()` and other operations
related to it (like `clear()`) if the container caches internally the position
@@ -3701,6 +3703,13 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_39_00 Boost 1.39 Release]
+
+* Optimized `list::merge` and `slist::merge`
+* `list::sort` and `slist::sort` are now stable.
+
+[endsect]
+
[section:release_notes_boost_1_38_00 Boost 1.38 Release]
* New treap-based containers: treap, treap_set, treap_multiset.
Modified: trunk/libs/intrusive/example/doc_any_hook.cpp
==============================================================================
--- trunk/libs/intrusive/example/doc_any_hook.cpp (original)
+++ trunk/libs/intrusive/example/doc_any_hook.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -34,7 +34,7 @@
typedef any_to_slist_hook < base_hook< any_base_hook<> > > BaseSlistOption;
typedef slist<MyClass, BaseSlistOption> BaseSList;
- //Define a member hook option that converts any_base_hook to a list hook
+ //Define a member hook option that converts any_member_hook to a list hook
typedef any_to_list_hook< member_hook
< MyClass, any_member_hook<>, &MyClass::member_hook_> > MemberListOption;
typedef list<MyClass, MemberListOption> MemberList;
Modified: trunk/libs/intrusive/proj/vc7ide/any_test/any_test.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/any_test/any_test.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/any_test/any_test.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/custom_bucket_traits/custom_bucket_traits.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/custom_bucket_traits/custom_bucket_traits.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/custom_bucket_traits/custom_bucket_traits.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/default_hook/default_hook.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/default_hook/default_hook.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/default_hook/default_hook.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/external_value_traits/external_value_traits.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/external_value_traits/external_value_traits.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/external_value_traits/external_value_traits.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/list/list.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/list/list.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/list/list.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/make_functions/make_functions.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/make_functions/make_functions.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/make_functions/make_functions.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/stateful_value_traits/stateful_value_traits.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/stateful_value_traits/stateful_value_traits.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/stateful_value_traits/stateful_value_traits.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/proj/vc7ide/to-do.txt
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/to-do.txt (original)
+++ trunk/libs/intrusive/proj/vc7ide/to-do.txt 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -24,3 +24,5 @@
-> revise strong exception safety concepts for treap::erase functions.
What happens with range deletions?
-> Assure stable order for optimize_multikey and inverse order otherwise
+-> linear slist's splice_after(..., slist &x) can be optimized if *this is empty
+-> optimize slist::merge like list::merge
Modified: trunk/libs/intrusive/proj/vc7ide/virtual_base/virtual_base.vcproj
==============================================================================
--- trunk/libs/intrusive/proj/vc7ide/virtual_base/virtual_base.vcproj (original)
+++ trunk/libs/intrusive/proj/vc7ide/virtual_base/virtual_base.vcproj 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -27,7 +27,7 @@
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
- DisableLanguageExtensions="FALSE"
+ DisableLanguageExtensions="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
Modified: trunk/libs/intrusive/test/slist_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/slist_test.cpp (original)
+++ trunk/libs/intrusive/test/slist_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -417,6 +417,28 @@
{ int init_values [] = { 2 };
TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
}
+ { //Now test swap when testlist2 is empty
+ list_type testlist1 (&values[0], &values[0] + 2);
+ list_type testlist2;
+ testlist1.swap(testlist2);
+ BOOST_TEST (testlist1.empty());
+ { int init_values [] = { 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
+ }
+ { //Now test swap when testlist1 is empty
+ list_type testlist2 (&values[0], &values[0] + 2);
+ list_type testlist1;
+ testlist1.swap(testlist2);
+ BOOST_TEST (testlist2.empty());
+ { int init_values [] = { 1, 2 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ }
+ { //Now test when both are empty
+ list_type testlist1, testlist2;
+ testlist2.swap(testlist1);
+ BOOST_TEST (testlist1.empty() && testlist2.empty());
+ }
+
if(!list_type::linear)
{
list_type testlist1 (&values[0], &values[0] + 2);
Modified: trunk/libs/intrusive/test/unordered_multiset_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/unordered_multiset_test.cpp (original)
+++ trunk/libs/intrusive/test/unordered_multiset_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -719,7 +719,6 @@
, false
, Incremental
>::test_all(data);
-
return 0;
}
};
@@ -740,7 +739,7 @@
< value_type
, typename hooks<VoidPointer>::base_hook_type
>::type
- , true
+ , false
, false
, Incremental
>::test_all(data);
@@ -752,7 +751,7 @@
, &value_type::node_
>
>::type
- , false
+ , true
, false
, Incremental
>::test_all(data);
@@ -761,8 +760,8 @@
< value_type
, typename hooks<VoidPointer>::auto_base_hook_type
>::type
- , true
- , true
+ , false
+ , false
, Incremental
>::test_all(data);
Modified: trunk/libs/intrusive/test/unordered_set_test.cpp
==============================================================================
--- trunk/libs/intrusive/test/unordered_set_test.cpp (original)
+++ trunk/libs/intrusive/test/unordered_set_test.cpp 2009-03-24 17:52:06 EDT (Tue, 24 Mar 2009)
@@ -623,7 +623,7 @@
< value_type
, typename hooks<VoidPointer>::auto_base_hook_type
>::type
- , true
+ , false
, true
, incremental
>::test_all(data);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk