summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/interprocess/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/interprocess/test
parentInitial commit. (diff)
downloadceph-upstream/16.2.11+ds.tar.xz
ceph-upstream/16.2.11+ds.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/interprocess/test')
-rw-r--r--src/boost/libs/interprocess/test/Jamfile.v240
-rw-r--r--src/boost/libs/interprocess/test/adaptive_node_pool_test.cpp30
-rw-r--r--src/boost/libs/interprocess/test/adaptive_pool_test.cpp71
-rw-r--r--src/boost/libs/interprocess/test/allocator_v1.hpp167
-rw-r--r--src/boost/libs/interprocess/test/allocexcept_test.cpp95
-rw-r--r--src/boost/libs/interprocess/test/anonymous_shared_memory_test.cpp54
-rw-r--r--src/boost/libs/interprocess/test/boost_interprocess_check.hpp27
-rw-r--r--src/boost/libs/interprocess/test/boost_use_windows_h.cpp38
-rw-r--r--src/boost/libs/interprocess/test/bufferstream_test.cpp144
-rw-r--r--src/boost/libs/interprocess/test/cached_adaptive_pool_test.cpp73
-rw-r--r--src/boost/libs/interprocess/test/cached_node_allocator_test.cpp67
-rw-r--r--src/boost/libs/interprocess/test/check_equal_containers.hpp92
-rw-r--r--src/boost/libs/interprocess/test/condition_any_test.cpp34
-rw-r--r--src/boost/libs/interprocess/test/condition_test.cpp40
-rw-r--r--src/boost/libs/interprocess/test/condition_test_template.hpp401
-rw-r--r--src/boost/libs/interprocess/test/data_test.cpp97
-rw-r--r--src/boost/libs/interprocess/test/deque_test.cpp312
-rw-r--r--src/boost/libs/interprocess/test/dummy_test_allocator.hpp149
-rw-r--r--src/boost/libs/interprocess/test/emplace_test.hpp627
-rw-r--r--src/boost/libs/interprocess/test/enable_shared_from_this_test.cpp97
-rw-r--r--src/boost/libs/interprocess/test/expand_bwd_test_allocator.hpp193
-rw-r--r--src/boost/libs/interprocess/test/expand_bwd_test_template.hpp269
-rw-r--r--src/boost/libs/interprocess/test/file_lock_test.cpp80
-rw-r--r--src/boost/libs/interprocess/test/file_mapping_test.cpp164
-rw-r--r--src/boost/libs/interprocess/test/flat_map_index_allocation_test.cpp25
-rw-r--r--src/boost/libs/interprocess/test/flat_tree_test.cpp202
-rw-r--r--src/boost/libs/interprocess/test/get_process_id_name.hpp71
-rw-r--r--src/boost/libs/interprocess/test/heap_allocator_v1.hpp166
-rw-r--r--src/boost/libs/interprocess/test/intermodule_singleton_test.cpp330
-rw-r--r--src/boost/libs/interprocess/test/intrusive_ptr_test.cpp546
-rw-r--r--src/boost/libs/interprocess/test/iset_index_allocation_test.cpp24
-rw-r--r--src/boost/libs/interprocess/test/iunordered_set_index_allocation_test.cpp25
-rw-r--r--src/boost/libs/interprocess/test/list_test.cpp63
-rw-r--r--src/boost/libs/interprocess/test/list_test.hpp281
-rw-r--r--src/boost/libs/interprocess/test/managed_mapped_file_test.cpp239
-rw-r--r--src/boost/libs/interprocess/test/managed_shared_memory_test.cpp216
-rw-r--r--src/boost/libs/interprocess/test/managed_windows_shared_memory_test.cpp152
-rw-r--r--src/boost/libs/interprocess/test/managed_xsi_shared_memory_test.cpp174
-rw-r--r--src/boost/libs/interprocess/test/map_index_allocation_test.cpp25
-rw-r--r--src/boost/libs/interprocess/test/map_test.hpp593
-rw-r--r--src/boost/libs/interprocess/test/mapped_file_test.cpp100
-rw-r--r--src/boost/libs/interprocess/test/memory_algorithm_test.cpp91
-rw-r--r--src/boost/libs/interprocess/test/memory_algorithm_test_template.hpp1036
-rw-r--r--src/boost/libs/interprocess/test/message_queue_test.cpp376
-rw-r--r--src/boost/libs/interprocess/test/movable_int.hpp293
-rw-r--r--src/boost/libs/interprocess/test/mutex_test.cpp37
-rw-r--r--src/boost/libs/interprocess/test/mutex_test_template.hpp394
-rw-r--r--src/boost/libs/interprocess/test/mutex_timeout_test.cpp30
-rw-r--r--src/boost/libs/interprocess/test/named_allocation_test_template.hpp495
-rw-r--r--src/boost/libs/interprocess/test/named_condition_any_test.cpp189
-rw-r--r--src/boost/libs/interprocess/test/named_condition_test.cpp189
-rw-r--r--src/boost/libs/interprocess/test/named_construct_test.cpp196
-rw-r--r--src/boost/libs/interprocess/test/named_creation_template.hpp132
-rw-r--r--src/boost/libs/interprocess/test/named_mutex_test.cpp38
-rw-r--r--src/boost/libs/interprocess/test/named_recursive_mutex_test.cpp41
-rw-r--r--src/boost/libs/interprocess/test/named_semaphore_test.cpp123
-rw-r--r--src/boost/libs/interprocess/test/named_sharable_mutex_test.cpp103
-rw-r--r--src/boost/libs/interprocess/test/named_upgradable_mutex_test.cpp103
-rw-r--r--src/boost/libs/interprocess/test/node_allocator_test.cpp66
-rw-r--r--src/boost/libs/interprocess/test/node_pool_test.cpp29
-rw-r--r--src/boost/libs/interprocess/test/node_pool_test.hpp163
-rw-r--r--src/boost/libs/interprocess/test/null_index_test.cpp51
-rw-r--r--src/boost/libs/interprocess/test/offset_ptr_test.cpp352
-rw-r--r--src/boost/libs/interprocess/test/print_container.hpp56
-rw-r--r--src/boost/libs/interprocess/test/private_adaptive_pool_test.cpp66
-rw-r--r--src/boost/libs/interprocess/test/private_node_allocator_test.cpp66
-rw-r--r--src/boost/libs/interprocess/test/recursive_mutex_test.cpp42
-rw-r--r--src/boost/libs/interprocess/test/robust_emulation_test.cpp22
-rw-r--r--src/boost/libs/interprocess/test/robust_mutex_test.hpp208
-rw-r--r--src/boost/libs/interprocess/test/robust_recursive_emulation_test.cpp23
-rw-r--r--src/boost/libs/interprocess/test/segment_manager_test.cpp478
-rw-r--r--src/boost/libs/interprocess/test/semaphore_test.cpp70
-rw-r--r--src/boost/libs/interprocess/test/set_test.hpp594
-rw-r--r--src/boost/libs/interprocess/test/sharable_mutex_test.cpp31
-rw-r--r--src/boost/libs/interprocess/test/sharable_mutex_test_template.hpp291
-rw-r--r--src/boost/libs/interprocess/test/shared_memory_mapping_test.cpp239
-rw-r--r--src/boost/libs/interprocess/test/shared_memory_test.cpp87
-rw-r--r--src/boost/libs/interprocess/test/shared_ptr_test.cpp615
-rw-r--r--src/boost/libs/interprocess/test/slist_test.cpp63
-rw-r--r--src/boost/libs/interprocess/test/stable_vector_test.cpp72
-rw-r--r--src/boost/libs/interprocess/test/string_test.cpp289
-rw-r--r--src/boost/libs/interprocess/test/tree_test.cpp199
-rw-r--r--src/boost/libs/interprocess/test/unique_ptr_test.cpp142
-rw-r--r--src/boost/libs/interprocess/test/unordered_test.cpp100
-rw-r--r--src/boost/libs/interprocess/test/upgradable_mutex_test.cpp173
-rw-r--r--src/boost/libs/interprocess/test/user_buffer_test.cpp259
-rw-r--r--src/boost/libs/interprocess/test/util.hpp95
-rw-r--r--src/boost/libs/interprocess/test/vector_test.cpp103
-rw-r--r--src/boost/libs/interprocess/test/vector_test.hpp254
-rw-r--r--src/boost/libs/interprocess/test/vectorstream_test.cpp185
-rw-r--r--src/boost/libs/interprocess/test/windows_shared_dir_func.cpp84
-rw-r--r--src/boost/libs/interprocess/test/windows_shared_memory_mapping_test.cpp138
-rw-r--r--src/boost/libs/interprocess/test/windows_shared_memory_test.cpp80
-rw-r--r--src/boost/libs/interprocess/test/xsi_shared_memory_mapping_test.cpp139
94 files changed, 16383 insertions, 0 deletions
diff --git a/src/boost/libs/interprocess/test/Jamfile.v2 b/src/boost/libs/interprocess/test/Jamfile.v2
new file mode 100644
index 000000000..a09bf8f28
--- /dev/null
+++ b/src/boost/libs/interprocess/test/Jamfile.v2
@@ -0,0 +1,40 @@
+# Boost Interprocess Library Test Jamfile
+
+# (C) Copyright Ion Gaztanaga 2006.
+# Use, modification and distribution are subject to 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)
+
+# Adapted from John Maddock's TR1 Jamfile.v2
+# Copyright John Maddock 2005.
+# Use, modification and distribution are subject to 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)
+
+# this rule enumerates through all the sources and invokes
+# the run rule for each source, the result is a list of all
+# the run rules, which we can pass on to the test_suite rule:
+
+rule test_all
+{
+ local all_rules = ;
+
+ for local fileb in [ glob *.cpp ]
+ {
+ all_rules += [ run $(fileb)
+ : # additional args
+ : # test-files
+ : # requirements
+ <toolset>acc:<linkflags>-lrt
+ <toolset>acc-pa_risc:<linkflags>-lrt
+ <toolset>gcc,<target-os>windows:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
+ <target-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
+ <target-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
+ <target-os>linux:<linkflags>"-lrt"
+ ] ;
+ }
+
+ return $(all_rules) ;
+}
+
+test-suite interprocess_test : [ test_all r ] : <threading>multi ;
diff --git a/src/boost/libs/interprocess/test/adaptive_node_pool_test.cpp b/src/boost/libs/interprocess/test/adaptive_node_pool_test.cpp
new file mode 100644
index 000000000..3caae188f
--- /dev/null
+++ b/src/boost/libs/interprocess/test/adaptive_node_pool_test.cpp
@@ -0,0 +1,30 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+#include <boost/interprocess/detail/config_begin.hpp>
+#include "node_pool_test.hpp"
+#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
+#include <vector>
+
+using namespace boost::interprocess;
+typedef managed_shared_memory::segment_manager segment_manager_t;
+
+int main ()
+{
+ typedef ipcdetail::private_adaptive_node_pool
+ <segment_manager_t, 4, 64, 64, 5> node_pool_t;
+
+ if(!test::test_all_node_pool<node_pool_t>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/adaptive_pool_test.cpp b/src/boost/libs/interprocess/test/adaptive_pool_test.cpp
new file mode 100644
index 000000000..59c7f979b
--- /dev/null
+++ b/src/boost/libs/interprocess/test/adaptive_pool_test.cpp
@@ -0,0 +1,71 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/adaptive_pool.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "list_test.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//We will work with wide characters for shared memory objects
+//Alias an adaptive pool that allocates ints
+typedef adaptive_pool
+ <int, managed_shared_memory::segment_manager> shmem_node_allocator_t;
+
+typedef ipcdetail::adaptive_pool_v1
+ <int, managed_shared_memory::segment_manager> shmem_node_allocator_v1_t;
+
+namespace boost {
+namespace interprocess {
+
+//Explicit instantiations to catch compilation errors
+template class adaptive_pool<int, managed_shared_memory::segment_manager>;
+template class adaptive_pool<void, managed_shared_memory::segment_manager>;
+
+namespace ipcdetail {
+
+template class ipcdetail::adaptive_pool_v1<int, managed_shared_memory::segment_manager>;
+template class ipcdetail::adaptive_pool_v1<void, managed_shared_memory::segment_manager>;
+
+}}}
+
+//Alias list types
+typedef list<int, shmem_node_allocator_t> MyShmList;
+typedef list<int, shmem_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, shmem_node_allocator_t> MyShmVector;
+typedef vector<int, shmem_node_allocator_v1_t> MyShmVectorV1;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyShmList, true>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/allocator_v1.hpp b/src/boost/libs/interprocess/test/allocator_v1.hpp
new file mode 100644
index 000000000..d68ef9f40
--- /dev/null
+++ b/src/boost/libs/interprocess/test/allocator_v1.hpp
@@ -0,0 +1,167 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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_ALLOCATOR_V1_HPP
+#define BOOST_INTERPROCESS_ALLOCATOR_V1_HPP
+
+#if defined (_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/intrusive/pointer_traits.hpp>
+
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/static_assert.hpp>
+
+//!\file
+//!Describes an allocator_v1 that allocates portions of fixed size
+//!memory buffer (shared memory, mapped file...)
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+//!An STL compatible allocator_v1 that uses a segment manager as
+//!memory source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator_v1 in shared memory, memory mapped-files, etc...*/
+template<class T, class SegmentManager>
+class allocator_v1
+{
+ private:
+ typedef allocator_v1<T, SegmentManager> self_t;
+ typedef SegmentManager segment_manager;
+ typedef typename segment_manager::void_pointer aux_pointer_t;
+
+ typedef typename boost::intrusive::
+ pointer_traits<aux_pointer_t>::template
+ rebind_pointer<const void>::type cvoid_ptr;
+
+ typedef typename boost::intrusive::
+ pointer_traits<cvoid_ptr>::template
+ rebind_pointer<segment_manager>::type alloc_ptr_t;
+
+ template<class T2, class SegmentManager2>
+ allocator_v1& operator=(const allocator_v1<T2, SegmentManager2>&);
+
+ allocator_v1& operator=(const allocator_v1&);
+
+ alloc_ptr_t mp_mngr;
+
+ public:
+ typedef T value_type;
+
+ typedef typename boost::intrusive::
+ pointer_traits<cvoid_ptr>::template
+ rebind_pointer<T>::type pointer;
+
+ typedef typename boost::intrusive::
+ pointer_traits<cvoid_ptr>::template
+ rebind_pointer<const T>::type const_pointer;
+
+ typedef typename ipcdetail::add_reference
+ <value_type>::type reference;
+ typedef typename ipcdetail::add_reference
+ <const value_type>::type const_reference;
+ typedef typename segment_manager::size_type size_type;
+ typedef typename segment_manager::difference_type difference_type;
+
+ //!Obtains an allocator_v1 of other type
+ template<class T2>
+ struct rebind
+ {
+ typedef allocator_v1<T2, SegmentManager> other;
+ };
+
+ //!Returns the segment manager. Never throws
+ segment_manager* get_segment_manager()const
+ { return ipcdetail::to_raw_pointer(mp_mngr); }
+/*
+ //!Returns address of mutable object. Never throws
+ pointer address(reference value) const
+ { return pointer(addressof(value)); }
+
+ //!Returns address of non mutable object. Never throws
+ const_pointer address(const_reference value) const
+ { return const_pointer(addressof(value)); }
+*/
+ //!Constructor from the segment manager. Never throws
+ allocator_v1(segment_manager *segment_mngr)
+ : mp_mngr(segment_mngr) { }
+
+ //!Constructor from other allocator_v1. Never throws
+ allocator_v1(const allocator_v1 &other)
+ : mp_mngr(other.get_segment_manager()){ }
+
+ //!Constructor from related allocator_v1. Never throws
+ template<class T2>
+ allocator_v1(const allocator_v1<T2, SegmentManager> &other)
+ : mp_mngr(other.get_segment_manager()){}
+
+ //!Allocates memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate(size_type count, cvoid_ptr hint = 0)
+ {
+ if(size_overflows<sizeof(T)>(count)){
+ throw bad_alloc();
+ }
+ (void)hint; return pointer(static_cast<T*>(mp_mngr->allocate(count*sizeof(T))));
+ }
+
+ //!Deallocates memory previously allocated. Never throws
+ void deallocate(const pointer &ptr, size_type)
+ { mp_mngr->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); }
+
+ //!Construct object, calling constructor.
+ //!Throws if T(const T&) throws
+ void construct(const pointer &ptr, const_reference value)
+ { new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(value); }
+
+ //!Destroys object. Throws if object's destructor throws
+ void destroy(const pointer &ptr)
+ { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
+
+ //!Returns the number of elements that could be allocated. Never throws
+ size_type max_size() const
+ { return mp_mngr->get_size(); }
+
+ //!Swap segment manager. Does not throw. If each allocator_v1 is placed in
+ //!different memory segments, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2)
+ { ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
+};
+
+//!Equality test for same type of allocator_v1
+template<class T, class SegmentManager> inline
+bool operator==(const allocator_v1<T , SegmentManager> &alloc1,
+ const allocator_v1<T, SegmentManager> &alloc2)
+ { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
+
+//!Inequality test for same type of allocator_v1
+template<class T, class SegmentManager> inline
+bool operator!=(const allocator_v1<T, SegmentManager> &alloc1,
+ const allocator_v1<T, SegmentManager> &alloc2)
+ { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_ALLOCATOR_V1_HPP
+
diff --git a/src/boost/libs/interprocess/test/allocexcept_test.cpp b/src/boost/libs/interprocess/test/allocexcept_test.cpp
new file mode 100644
index 000000000..696b27973
--- /dev/null
+++ b/src/boost/libs/interprocess/test/allocexcept_test.cpp
@@ -0,0 +1,95 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/allocators/allocator.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <iostream>
+#include <functional>
+#include "print_container.hpp"
+#include <string>
+#include "get_process_id_name.hpp"
+
+struct InstanceCounter
+{
+ InstanceCounter(){++counter;}
+ InstanceCounter(const InstanceCounter&){++counter;}
+ ~InstanceCounter(){--counter;}
+ static std::size_t counter;
+};
+
+std::size_t InstanceCounter::counter = 0;
+
+using namespace boost::interprocess;
+
+
+int main ()
+{
+ const int memsize = 16384;
+ const char *const shMemName = test::get_process_id_name();
+
+ try{
+ shared_memory_object::remove(shMemName);
+
+ //Named allocate capable shared mem allocator
+ managed_shared_memory segment(create_only, shMemName, memsize);
+
+ //STL compatible allocator object, uses allocate(), deallocate() functions
+ typedef allocator<InstanceCounter,
+ managed_shared_memory::segment_manager>
+ inst_allocator_t;
+ const inst_allocator_t myallocator (segment.get_segment_manager());
+
+ typedef vector<InstanceCounter, inst_allocator_t> MyVect;
+
+ //We'll provoke an exception, let's see if exception handling works
+ try{
+ //Fill vector until there is no more memory
+ MyVect myvec(myallocator);
+ int i;
+ for(i = 0; true; ++i){
+ myvec.push_back(InstanceCounter());
+ }
+ }
+ catch(boost::interprocess::bad_alloc &){
+ if(InstanceCounter::counter != 0)
+ return 1;
+ }
+
+ //We'll provoke an exception, let's see if exception handling works
+ try{
+ //Fill vector at the beginning until there is no more memory
+ MyVect myvec(myallocator);
+ int i;
+ InstanceCounter ic;
+ for(i = 0; true; ++i){
+ myvec.insert(myvec.begin(), i, ic);
+ }
+ }
+ catch(boost::interprocess::bad_alloc &){
+ if(InstanceCounter::counter != 0)
+ return 1;
+ }
+ catch(std::length_error &){
+ if(InstanceCounter::counter != 0)
+ return 1;
+ }
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/anonymous_shared_memory_test.cpp b/src/boost/libs/interprocess/test/anonymous_shared_memory_test.cpp
new file mode 100644
index 000000000..cdff6e66f
--- /dev/null
+++ b/src/boost/libs/interprocess/test/anonymous_shared_memory_test.cpp
@@ -0,0 +1,54 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <iostream>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/anonymous_shared_memory.hpp>
+#include <cstddef>
+#include <exception>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ const std::size_t MemSize = 99999*2;
+ {
+ //Now check anonymous mapping
+ mapped_region region(anonymous_shared_memory(MemSize));
+
+ //Write pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < MemSize
+ ;++i, ++pattern){
+ *pattern = static_cast<unsigned char>(i);
+ }
+
+ //Check pattern
+ pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < MemSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+ }
+ catch(std::exception &exc){
+ std::cout << "Unhandled exception: " << exc.what() << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/boost_interprocess_check.hpp b/src/boost/libs/interprocess/test/boost_interprocess_check.hpp
new file mode 100644
index 000000000..675613c99
--- /dev/null
+++ b/src/boost/libs/interprocess/test/boost_interprocess_check.hpp
@@ -0,0 +1,27 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_TEST_CHECK_HEADER
+#define BOOST_INTERPROCESS_TEST_CHECK_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <iostream>
+
+namespace boost { namespace interprocess { namespace test {
+
+#define BOOST_INTERPROCESS_CHECK( P ) \
+ if(!(P)) do{ assert(P); std::cout << "Failed: " << #P << " file: " << __FILE__ << " line : " << __LINE__ << std::endl; throw boost::interprocess::interprocess_exception(#P);}while(0)
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_TEST_CHECK_HEADER
diff --git a/src/boost/libs/interprocess/test/boost_use_windows_h.cpp b/src/boost/libs/interprocess/test/boost_use_windows_h.cpp
new file mode 100644
index 000000000..2fb1a612d
--- /dev/null
+++ b/src/boost/libs/interprocess/test/boost_use_windows_h.cpp
@@ -0,0 +1,38 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#define _WIN32_WINNT 0x0501
+#define BOOST_USE_WINDOWS_H
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#ifdef BOOST_INTERPROCESS_WINDOWS
+
+#include <boost/interprocess/windows_shared_memory.hpp>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ windows_shared_memory dummy;
+ static_cast<void>(dummy);
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/bufferstream_test.cpp b/src/boost/libs/interprocess/test/bufferstream_test.cpp
new file mode 100644
index 000000000..6b6cb24c2
--- /dev/null
+++ b/src/boost/libs/interprocess/test/bufferstream_test.cpp
@@ -0,0 +1,144 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/streams/bufferstream.hpp>
+#include <sstream>
+#include <cstring>
+
+namespace boost{
+namespace interprocess{
+
+//Force instantiations to catch compile-time errors
+template class basic_bufferbuf<char>;
+template class basic_bufferstream<char>;
+template class basic_ibufferstream<char>;
+template class basic_obufferstream<char>;
+
+}}
+
+using namespace boost::interprocess;
+
+static int bufferstream_test()
+{
+ //Static big enough buffer
+ {
+ const int BufSize = 10001;
+ //This will be zero-initialized
+ static char buffer [BufSize];
+ bufferstream bufstream;
+ if(bufstream.tellg() != std::streampos(0)){
+ return 1;
+ }
+ if(bufstream.tellp() != std::streampos(0)){
+ return 1;
+ }
+ std::stringstream std_stringstream;
+ std::string str1, str2, str3("testline:");
+ int number1, number2;
+
+ //Make sure we have null in the last byte
+ bufstream.buffer(buffer, BufSize-1);
+ for(int i = 0; i < 100; ++i){
+ bufstream << "testline: " << i << std::endl;
+ std_stringstream << "testline: " << i << std::endl;
+ }
+
+ if(std::strcmp(buffer, std_stringstream.str().c_str()) != 0){
+ return 1;
+ }
+
+ //We shouldn't have reached the end of the buffer writing
+ if(bufstream.bad()){
+ assert(0);
+ return 1;
+ }
+
+ bufstream.buffer(buffer, BufSize-1);
+ for(int i = 0; i < 100; ++i){
+ bufstream >> str1 >> number1;
+ std_stringstream >> str2 >> number2;
+ if((str1 != str2) || (str1 != str3)){
+ assert(0); return 1;
+ }
+ if((number1 != number2) || (number1 != i)){
+ assert(0); return 1;
+ }
+ }
+ //We shouldn't have reached the end of the buffer reading
+ if(bufstream.eof()){
+ assert(0);
+ return 1;
+ }
+ }
+
+ //Static small buffer. Check if buffer
+ //overflow protection works.
+ {
+ const int BufSize = 101;
+ //This will be zero-initialized
+ static char buffer [BufSize];
+ bufferstream bufstream;
+ std::stringstream std_stringstream;
+ std::string str1;
+ int number1;
+
+ //Make sure we have null in the last byte
+ bufstream.buffer(buffer, BufSize-1);
+ for(int i = 0; i < 100; ++i){
+ bufstream << "testline: " << i << std::endl;
+ std_stringstream << "testline: " << i << std::endl;
+ }
+
+ //Contents should be different
+ if(std::strcmp(buffer, std_stringstream.str().c_str()) == 0){
+ return 1;
+ }
+ //The stream shouldn't be in good health
+ if(bufstream.good()){
+ assert(0);
+ return 1;
+ }
+ //The bad flag should be active. This indicates overflow attempt
+ if(!bufstream.bad()){
+ assert(0);
+ return 1;
+ }
+
+ //Now let's test read overflow
+ bufstream.clear();
+ bufstream.buffer(buffer, BufSize-1);
+ for(int i = 0; i < 100; ++i){
+ bufstream >> str1 >> number1;
+ }
+ //The stream shouldn't be in good health
+ if(bufstream.good()){
+ assert(0);
+ return 1;
+ }
+ //The eof flag indicates we have reached the end of the
+ //buffer while reading
+ if(!bufstream.eof()){
+ assert(0);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main ()
+{
+ if(bufferstream_test()){
+ return 1;
+ }
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/cached_adaptive_pool_test.cpp b/src/boost/libs/interprocess/test/cached_adaptive_pool_test.cpp
new file mode 100644
index 000000000..ee5b86c2d
--- /dev/null
+++ b/src/boost/libs/interprocess/test/cached_adaptive_pool_test.cpp
@@ -0,0 +1,73 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/cached_adaptive_pool.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "list_test.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//We will work with wide characters for shared memory objects
+//Alias an cached adaptive pool that allocates ints
+typedef cached_adaptive_pool
+ <int, managed_shared_memory::segment_manager>
+ cached_node_allocator_t;
+
+typedef ipcdetail::cached_adaptive_pool_v1
+ <int, managed_shared_memory::segment_manager>
+ cached_node_allocator_v1_t;
+
+namespace boost {
+namespace interprocess {
+
+//Explicit instantiations to catch compilation errors
+template class cached_adaptive_pool<int, managed_shared_memory::segment_manager>;
+template class cached_adaptive_pool<void, managed_shared_memory::segment_manager>;
+
+namespace ipcdetail {
+
+template class ipcdetail::cached_adaptive_pool_v1<int, managed_shared_memory::segment_manager>;
+template class ipcdetail::cached_adaptive_pool_v1<void, managed_shared_memory::segment_manager>;
+
+}}}
+
+//Alias list types
+typedef list<int, cached_node_allocator_t> MyShmList;
+typedef list<int, cached_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, cached_node_allocator_t> MyShmVector;
+typedef vector<int, cached_node_allocator_v1_t> MyShmVectorV1;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyShmList, true>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/cached_node_allocator_test.cpp b/src/boost/libs/interprocess/test/cached_node_allocator_test.cpp
new file mode 100644
index 000000000..8ffa0f0b2
--- /dev/null
+++ b/src/boost/libs/interprocess/test/cached_node_allocator_test.cpp
@@ -0,0 +1,67 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/cached_node_allocator.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "list_test.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//Alias an integer node allocator type
+typedef cached_node_allocator
+ <int, managed_shared_memory::segment_manager>
+ cached_node_allocator_t;
+typedef ipcdetail::cached_node_allocator_v1
+ <int, managed_shared_memory::segment_manager>
+ cached_node_allocator_v1_t;
+
+namespace boost {
+namespace interprocess {
+
+//Explicit instantiations to catch compilation errors
+template class cached_node_allocator<int, managed_shared_memory::segment_manager>;
+template class cached_node_allocator<void, managed_shared_memory::segment_manager>;
+
+namespace ipcdetail {
+
+template class ipcdetail::cached_node_allocator_v1<int, managed_shared_memory::segment_manager>;
+template class ipcdetail::cached_node_allocator_v1<void, managed_shared_memory::segment_manager>;
+
+}}}
+
+//Alias list types
+typedef list<int, cached_node_allocator_t> MyShmList;
+typedef list<int, cached_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, cached_node_allocator_t> MyShmVector;
+typedef vector<int, cached_node_allocator_v1_t> MyShmVectorV1;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyShmList, true>())
+ return 1;
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/check_equal_containers.hpp b/src/boost/libs/interprocess/test/check_equal_containers.hpp
new file mode 100644
index 000000000..423a84cd8
--- /dev/null
+++ b/src/boost/libs/interprocess/test/check_equal_containers.hpp
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_TEST_CHECK_EQUAL_CONTAINERS_HPP
+#define BOOST_INTERPROCESS_TEST_CHECK_EQUAL_CONTAINERS_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+// container/detail
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/pair.hpp>
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template< class T1, class T2>
+bool CheckEqual( const T1 &t1, const T2 &t2
+ , typename boost::container::dtl::enable_if_c
+ <!boost::container::dtl::is_pair<T1>::value &&
+ !boost::container::dtl::is_pair<T2>::value
+ >::type* = 0)
+{ return t1 == t2; }
+
+template< class Pair1, class Pair2>
+bool CheckEqual( const Pair1 &pair1, const Pair2 &pair2
+ , typename boost::container::dtl::enable_if_c
+ <boost::container::dtl::is_pair<Pair1>::value &&
+ boost::container::dtl::is_pair<Pair2>::value
+ >::type* = 0)
+{
+ return CheckEqual(pair1.first, pair2.first) && CheckEqual(pair1.second, pair2.second);
+}
+
+
+//Function to check if both containers are equal
+template<class MyShmCont
+ ,class MyStdCont>
+bool CheckEqualContainers(MyShmCont *shmcont, MyStdCont *stdcont)
+{
+ if(shmcont->size() != stdcont->size())
+ return false;
+
+ typename MyShmCont::iterator itshm(shmcont->begin()), itshmend(shmcont->end());
+ typename MyStdCont::iterator itstd(stdcont->begin());
+ typename MyStdCont::size_type dist =
+ typename MyStdCont::size_type(boost::container::iterator_distance(itshm, itshmend));
+ if(dist != shmcont->size()){
+ return false;
+ }
+ std::size_t i = 0;
+ for(; itshm != itshmend; ++itshm, ++itstd, ++i){
+ if(!CheckEqual(*itstd, *itshm))
+ return false;
+ }
+ return true;
+}
+
+template<class MyShmCont
+ ,class MyStdCont>
+bool CheckEqualPairContainers(MyShmCont *shmcont, MyStdCont *stdcont)
+{
+ if(shmcont->size() != stdcont->size())
+ return false;
+
+ typedef typename MyShmCont::key_type key_type;
+ typedef typename MyShmCont::mapped_type mapped_type;
+
+ typename MyShmCont::iterator itshm(shmcont->begin()), itshmend(shmcont->end());
+ typename MyStdCont::iterator itstd(stdcont->begin());
+ for(; itshm != itshmend; ++itshm, ++itstd){
+ if(itshm->first != key_type(itstd->first))
+ return false;
+
+ if(itshm->second != mapped_type(itstd->second))
+ return false;
+ }
+ return true;
+}
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_CHECK_EQUAL_CONTAINERS_HPP
diff --git a/src/boost/libs/interprocess/test/condition_any_test.cpp b/src/boost/libs/interprocess/test/condition_any_test.cpp
new file mode 100644
index 000000000..8349fed3b
--- /dev/null
+++ b/src/boost/libs/interprocess/test/condition_any_test.cpp
@@ -0,0 +1,34 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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>
+#include <boost/interprocess/sync/interprocess_condition_any.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/interprocess/sync/spin/mutex.hpp>
+
+#include "condition_test_template.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ if(!test::do_test_condition<interprocess_condition_any, interprocess_mutex>())
+ return 1;
+ if(!test::do_test_condition<interprocess_condition_any, ipcdetail::spin_mutex>())
+ return 1;
+ if(!test::do_test_condition<interprocess_condition_any, interprocess_recursive_mutex>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/condition_test.cpp b/src/boost/libs/interprocess/test/condition_test.cpp
new file mode 100644
index 000000000..089c0a6f2
--- /dev/null
+++ b/src/boost/libs/interprocess/test/condition_test.cpp
@@ -0,0 +1,40 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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>
+#include <boost/interprocess/sync/interprocess_condition.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include "condition_test_template.hpp"
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+#include <boost/interprocess/sync/windows/condition.hpp>
+#include <boost/interprocess/sync/windows/mutex.hpp>
+#include <boost/interprocess/sync/spin/condition.hpp>
+#include <boost/interprocess/sync/spin/mutex.hpp>
+#endif
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ #if defined(BOOST_INTERPROCESS_WINDOWS)
+ if(!test::do_test_condition<ipcdetail::windows_condition, ipcdetail::windows_mutex>())
+ return 1;
+ if(!test::do_test_condition<ipcdetail::spin_condition, ipcdetail::spin_mutex>())
+ return 1;
+ #endif
+ if(!test::do_test_condition<interprocess_condition, interprocess_mutex>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/condition_test_template.hpp b/src/boost/libs/interprocess/test/condition_test_template.hpp
new file mode 100644
index 000000000..03e80ba44
--- /dev/null
+++ b/src/boost/libs/interprocess/test/condition_test_template.hpp
@@ -0,0 +1,401 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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. William E. Kempf 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-2012. 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_CONDITION_TEST_TEMPLATE_HPP
+#define BOOST_INTERPROCESS_CONDITION_TEST_TEMPLATE_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include "boost_interprocess_check.hpp"
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <iostream>
+
+namespace boost{
+namespace interprocess{
+namespace test {
+
+boost::posix_time::ptime ptime_delay(int secs)
+{
+ return microsec_clock::universal_time() +
+ boost::posix_time::time_duration(0, 0, secs);
+}
+
+template <typename F, typename T>
+class binder
+{
+public:
+ binder(const F& f, const T& p)
+ : func(f), param(p) { }
+ void operator()() const { func(param); }
+
+private:
+ F func;
+ T param;
+};
+
+template <typename F, typename T>
+binder<F, T> bind_function(F func, T param)
+{
+ return binder<F, T>(func, param);
+}
+
+template <class Condition, class Mutex>
+struct condition_test_data
+{
+ condition_test_data() : notified(0), awoken(0) { }
+
+ ~condition_test_data()
+ {}
+
+ Mutex mutex;
+ Condition condition;
+ int notified;
+ int awoken;
+};
+
+template <class Condition, class Mutex>
+void condition_test_thread(condition_test_data<Condition, Mutex>* data)
+{
+ boost::interprocess::scoped_lock<Mutex>
+ lock(data->mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ while (!(data->notified > 0))
+ data->condition.wait(lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ data->awoken++;
+}
+
+struct cond_predicate
+{
+ cond_predicate(int& var, int val) : _var(var), _val(val) { }
+
+ bool operator()() { return _var == _val; }
+
+ int& _var;
+ int _val;
+};
+
+template <class Condition, class Mutex>
+void condition_test_waits(condition_test_data<Condition, Mutex>* data)
+{
+ boost::interprocess::scoped_lock<Mutex>
+ lock(data->mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+
+ // Test wait.
+ while (data->notified != 1)
+ data->condition.wait(lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data->notified == 1);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test predicate wait.
+ data->condition.wait(lock, cond_predicate(data->notified, 2));
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data->notified == 2);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test timed_wait.
+ while (data->notified != 3)
+ data->condition.timed_wait(lock, ptime_delay(5));
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data->notified == 3);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test predicate timed_wait.
+ cond_predicate pred(data->notified, 4);
+ bool ret = data->condition.timed_wait(lock, ptime_delay(5), pred);
+ BOOST_INTERPROCESS_CHECK(ret);(void)ret;
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(pred());
+ BOOST_INTERPROCESS_CHECK(data->notified == 4);
+ data->awoken++;
+ data->condition.notify_one();
+}
+
+template <class Condition, class Mutex>
+void do_test_condition_notify_one()
+{
+ condition_test_data<Condition, Mutex> data;
+
+ boost::interprocess::ipcdetail::OS_thread_t thread;
+ boost::interprocess::ipcdetail::thread_launch(thread, bind_function(&condition_test_thread<Condition, Mutex>, &data));
+ //Make sure thread is blocked
+ boost::interprocess::ipcdetail::thread_sleep(1000);
+ {
+ boost::interprocess::scoped_lock<Mutex>
+ lock(data.mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ data.notified++;
+ data.condition.notify_one();
+ }
+
+ boost::interprocess::ipcdetail::thread_join(thread);
+ BOOST_INTERPROCESS_CHECK(data.awoken == 1);
+}
+
+template <class Condition, class Mutex>
+void do_test_condition_notify_all()
+{
+ const int NUMTHREADS = 3;
+
+ boost::interprocess::ipcdetail::OS_thread_t thgroup[NUMTHREADS];
+ condition_test_data<Condition, Mutex> data;
+
+ for(int i = 0; i< NUMTHREADS; ++i){
+ boost::interprocess::ipcdetail::thread_launch(thgroup[i], bind_function(&condition_test_thread<Condition, Mutex>, &data));
+ }
+
+ //Make sure all threads are blocked
+ boost::interprocess::ipcdetail::thread_sleep(1000);
+ {
+ boost::interprocess::scoped_lock<Mutex>
+ lock(data.mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ data.notified++;
+ }
+ data.condition.notify_all();
+
+ for(int i = 0; i< NUMTHREADS; ++i){
+ boost::interprocess::ipcdetail::thread_join(thgroup[i]);
+ }
+ BOOST_INTERPROCESS_CHECK(data.awoken == NUMTHREADS);
+}
+
+template <class Condition, class Mutex>
+void do_test_condition_waits()
+{
+ condition_test_data<Condition, Mutex> data;
+ boost::interprocess::ipcdetail::OS_thread_t thread;
+ boost::interprocess::ipcdetail::thread_launch(thread, bind_function(&condition_test_waits<Condition, Mutex>, &data));
+
+ {
+ boost::interprocess::scoped_lock<Mutex>
+ lock(data.mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+
+ boost::interprocess::ipcdetail::thread_sleep(1000);
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 1)
+ data.condition.wait(lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data.awoken == 1);
+
+ boost::interprocess::ipcdetail::thread_sleep(1000);
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 2)
+ data.condition.wait(lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data.awoken == 2);
+
+ boost::interprocess::ipcdetail::thread_sleep(1000);
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 3)
+ data.condition.wait(lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data.awoken == 3);
+
+ boost::interprocess::ipcdetail::thread_sleep(1000);
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 4)
+ data.condition.wait(lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ BOOST_INTERPROCESS_CHECK(data.awoken == 4);
+ }
+
+ boost::interprocess::ipcdetail::thread_join(thread);
+ BOOST_INTERPROCESS_CHECK(data.awoken == 4);
+}
+/*
+//Message queue simulation test
+template <class Condition>
+inline Condition &cond_empty()
+{
+ static Condition cond_empty;
+ return cond_empty;
+}
+
+template <class Condition>
+inline Condition &cond_full()
+{
+ static Condition cond_full;
+ return cond_full;
+}
+
+
+template <class Mutex>
+inline Mutex &mutex()
+{
+ static Mutex mut;
+ return mut;
+}
+*/
+static volatile int count = 0;
+static volatile int waiting_readers = 0;
+static volatile int waiting_writer = 0;
+const int queue_size = 3;
+const int thread_factor = 10;
+const int NumThreads = thread_factor*queue_size;
+
+//Function that removes items from queue
+template <class Condition, class Mutex>
+struct condition_func
+{
+ condition_func(Condition &cond_full, Condition &cond_empty, Mutex &mutex)
+ : cond_full_(cond_full), cond_empty_(cond_empty), mutex_(mutex)
+ {}
+
+ void operator()()
+ {
+ boost::interprocess::scoped_lock<Mutex>lock(mutex_);
+ while(count == 0){
+ ++waiting_readers;
+ cond_empty_.wait(lock);
+ --waiting_readers;
+ }
+ --count;
+ if(waiting_writer)
+ cond_full_.notify_one();
+ }
+ Condition &cond_full_;
+ Condition &cond_empty_;
+ Mutex &mutex_;
+};
+
+//Queue functions
+template <class Condition, class Mutex>
+void do_test_condition_queue_notify_one(void)
+{
+ //Force mutex and condition creation
+ Condition cond_empty;
+ Condition cond_full;
+ Mutex mutex;
+
+ //Create threads that will decrease count
+ {
+ //Initialize counters
+ count = 0;
+ waiting_readers = 0;
+ waiting_writer = 0;
+
+ boost::interprocess::ipcdetail::OS_thread_t thgroup[NumThreads];
+ for(int i = 0; i< NumThreads; ++i){
+ condition_func<Condition, Mutex> func(cond_full, cond_empty, mutex);
+ boost::interprocess::ipcdetail::thread_launch(thgroup[i], func);
+ }
+
+ //Add 20 elements one by one in the queue simulation
+ //The sender will block if it fills the queue
+ for(int i = 0; i < NumThreads; ++i){
+ boost::interprocess::scoped_lock<Mutex> lock(mutex);
+ while(count == queue_size){
+ ++waiting_writer;
+ cond_full.wait(lock);
+ --waiting_writer;
+ }
+ count++;
+
+ if(waiting_readers)
+ cond_empty.notify_one();
+ }
+ for(int i = 0; i< NumThreads; ++i){
+ boost::interprocess::ipcdetail::thread_join(thgroup[i]);
+ }
+ BOOST_INTERPROCESS_CHECK(count == 0);
+ BOOST_INTERPROCESS_CHECK(waiting_readers == 0);
+ BOOST_INTERPROCESS_CHECK(waiting_writer == 0);
+ }
+}
+
+//Queue functions
+template <class Condition, class Mutex>
+void do_test_condition_queue_notify_all(void)
+{
+ //Force mutex and condition creation
+ Condition cond_empty;
+ Condition cond_full;
+ Mutex mutex;
+
+ //Create threads that will decrease count
+ {
+ //Initialize counters
+ count = 0;
+ waiting_readers = 0;
+ waiting_writer = 0;
+
+ boost::interprocess::ipcdetail::OS_thread_t thgroup[NumThreads];
+ for(int i = 0; i< NumThreads; ++i){
+ condition_func<Condition, Mutex> func(cond_full, cond_empty, mutex);
+ boost::interprocess::ipcdetail::thread_launch(thgroup[i], func);
+ }
+
+ //Fill queue to the max size and notify all several times
+ for(int i = 0; i < NumThreads; ++i){
+ boost::interprocess::scoped_lock<Mutex>lock(mutex);
+ while(count == queue_size){
+ ++waiting_writer;
+ cond_full.wait(lock);
+ --waiting_writer;
+ }
+ count++;
+
+ if(waiting_readers)
+ cond_empty.notify_all();
+ }
+ for(int i = 0; i< NumThreads; ++i){
+ boost::interprocess::ipcdetail::thread_join(thgroup[i]);
+ }
+ BOOST_INTERPROCESS_CHECK(count == 0);
+ BOOST_INTERPROCESS_CHECK(waiting_readers == 0);
+ BOOST_INTERPROCESS_CHECK(waiting_writer == 0);
+ }
+}
+
+template <class Condition, class Mutex>
+bool do_test_condition()
+{
+ std::cout << "do_test_condition_notify_one<" << typeid(Condition).name() << "," << typeid(Mutex).name() << '\n' << std::endl;
+ do_test_condition_notify_one<Condition, Mutex>();
+ std::cout << "do_test_condition_notify_all<" << typeid(Condition).name() << "," << typeid(Mutex).name() << '\n' << std::endl;
+ do_test_condition_notify_all<Condition, Mutex>();
+ std::cout << "do_test_condition_waits<" << typeid(Condition).name() << "," << typeid(Mutex).name() << '\n' << std::endl;
+ do_test_condition_waits<Condition, Mutex>();
+ std::cout << "do_test_condition_queue_notify_one<" << typeid(Condition).name() << "," << typeid(Mutex).name() << '\n' << std::endl;
+ do_test_condition_queue_notify_one<Condition, Mutex>();
+ std::cout << "do_test_condition_queue_notify_all<" << typeid(Condition).name() << "," << typeid(Mutex).name() << '\n' << std::endl;
+ do_test_condition_queue_notify_all<Condition, Mutex>();
+ return true;
+}
+
+} //namespace test
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_CONDITION_TEST_TEMPLATE_HPP
diff --git a/src/boost/libs/interprocess/test/data_test.cpp b/src/boost/libs/interprocess/test/data_test.cpp
new file mode 100644
index 000000000..450031b26
--- /dev/null
+++ b/src/boost/libs/interprocess/test/data_test.cpp
@@ -0,0 +1,97 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/allocators/allocator.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <functional>
+#include <string>
+#include "print_container.hpp"
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ const int memsize = 65536;
+ std::string process_name;
+ test::get_process_id_name(process_name);
+ const char *const shMemName = process_name.c_str();
+
+ try{
+ shared_memory_object::remove(shMemName);
+
+ //Create shared memory
+ managed_shared_memory segment(create_only, shMemName, memsize);
+
+ //STL compatible allocator object, uses allocate(), deallocate() functions
+ typedef allocator<int, managed_shared_memory::segment_manager>
+ shmem_allocator_int_t;
+
+ const shmem_allocator_int_t myallocator (segment.get_segment_manager());
+
+ const int max = 100;
+ void *array[max];
+
+ const char *allocName = "testAllocation";
+
+ typedef boost::interprocess::vector<int, shmem_allocator_int_t > MyVect;
+
+ //---- ALLOC, NAMED_ALLOC, NAMED_NEW TEST ----//
+ {
+ int i;
+ //Let's allocate some memory
+ for(i = 0; i < max; ++i){
+ array[i] = segment.allocate(i+1);
+ }
+
+ //Deallocate allocated memory
+ for(i = 0; i < max; ++i){
+ segment.deallocate(array[i]);
+ }
+
+ bool res;
+
+ MyVect *shmem_vect;
+
+ //Construct and find
+ shmem_vect = segment.construct<MyVect> (allocName) (myallocator);
+ res = (shmem_vect == segment.find<MyVect>(allocName).first);
+ if(!res)
+ return 1;
+ //Destroy and check it is not present
+ segment.destroy<MyVect> (allocName);
+ res = (0 == segment.find<MyVect>(allocName).first);
+ if(!res)
+ return 1;
+
+ //Construct, dump to a file
+ shmem_vect = segment.construct<MyVect> (allocName) (myallocator);
+
+ if(shmem_vect != segment.find<MyVect>(allocName).first)
+ return 1;
+ //Destroy and check it is not present
+ segment.destroy<MyVect> (allocName);
+ res = (0 == segment.find<MyVect>(allocName).first);
+ if(!res)
+ return 1;
+ }
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/deque_test.cpp b/src/boost/libs/interprocess/test/deque_test.cpp
new file mode 100644
index 000000000..4b3ee3cd1
--- /dev/null
+++ b/src/boost/libs/interprocess/test/deque_test.cpp
@@ -0,0 +1,312 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <memory>
+#include <deque>
+#include <iostream>
+#include <list>
+
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/deque.hpp>
+#include <boost/interprocess/indexes/flat_map_index.hpp>
+#include "print_container.hpp"
+#include "check_equal_containers.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include <boost/interprocess/allocators/allocator.hpp>
+#include "allocator_v1.hpp"
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <string>
+#include "get_process_id_name.hpp"
+#include "emplace_test.hpp"
+
+///////////////////////////////////////////////////////////////////
+// //
+// This example repeats the same operations with std::deque and //
+// shmem_deque using the node allocator //
+// and compares the values of both containers //
+// //
+///////////////////////////////////////////////////////////////////
+
+using namespace boost::interprocess;
+
+//Function to check if both sets are equal
+template<class V1, class V2>
+bool copyable_only(V1 *, V2 *, ipcdetail::false_type)
+{
+ return true;
+}
+
+//Function to check if both sets are equal
+template<class V1, class V2>
+bool copyable_only(V1 *shmdeque, V2 *stddeque, ipcdetail::true_type)
+{
+ typedef typename V1::value_type IntType;
+ std::size_t size = shmdeque->size();
+ stddeque->insert(stddeque->end(), 50, 1);
+ shmdeque->insert(shmdeque->end(), 50, IntType(1));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ {
+ IntType move_me(1);
+ stddeque->insert(stddeque->begin()+size/2, 50, 1);
+ shmdeque->insert(shmdeque->begin()+size/2, 50, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+ {
+ IntType move_me(2);
+ shmdeque->assign(shmdeque->size()/2, boost::move(move_me));
+ stddeque->assign(stddeque->size()/2, 2);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+ {
+ IntType move_me(1);
+ stddeque->clear();
+ shmdeque->clear();
+ stddeque->insert(stddeque->begin(), 50, 1);
+ shmdeque->insert(shmdeque->begin(), 50, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->begin()+20, 50, 1);
+ shmdeque->insert(shmdeque->begin()+20, 50, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->begin()+20, 20, 1);
+ shmdeque->insert(shmdeque->begin()+20, 20, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+ {
+ IntType move_me(1);
+ stddeque->clear();
+ shmdeque->clear();
+ stddeque->insert(stddeque->end(), 50, 1);
+ shmdeque->insert(shmdeque->end(), 50, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->end()-20, 50, 1);
+ shmdeque->insert(shmdeque->end()-20, 50, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ stddeque->insert(stddeque->end()-20, 20, 1);
+ shmdeque->insert(shmdeque->end()-20, 20, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+
+ return true;
+}
+
+
+template<class IntType, template<class T, class SegmentManager> class AllocatorType >
+bool do_test()
+{
+ //Customize managed_shared_memory class
+ typedef basic_managed_shared_memory
+ <char,
+ //simple_seq_fit<mutex_family>,
+ rbtree_best_fit<mutex_family>,
+ //flat_map_index
+ iset_index
+ > my_managed_shared_memory;
+
+ //Alias AllocatorType type
+ typedef AllocatorType<IntType, my_managed_shared_memory::segment_manager>
+ shmem_allocator_t;
+
+ //Alias deque types
+ typedef deque<IntType, shmem_allocator_t> MyShmDeque;
+ typedef std::deque<int> MyStdDeque;
+ const int Memsize = 65536;
+ const char *const shMemName = test::get_process_id_name();
+ const int max = 100;
+
+ /*try*/{
+ shared_memory_object::remove(shMemName);
+
+ //Create shared memory
+ my_managed_shared_memory segment(create_only, shMemName, Memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmDeque *shmdeque = segment.template construct<MyShmDeque>("MyShmDeque")
+ (segment.get_segment_manager());
+
+ MyStdDeque *stddeque = new MyStdDeque;
+
+ /*try*/{
+ //Compare several shared memory deque operations with std::deque
+ for(int i = 0; i < max*50; ++i){
+ IntType move_me(i);
+ shmdeque->insert(shmdeque->end(), boost::move(move_me));
+ stddeque->insert(stddeque->end(), i);
+ shmdeque->insert(shmdeque->end(), IntType(i));
+ stddeque->insert(stddeque->end(), int(i));
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ shmdeque->clear();
+ stddeque->clear();
+
+ for(int i = 0; i < max*50; ++i){
+ IntType move_me(i);
+ shmdeque->push_back(boost::move(move_me));
+ stddeque->push_back(i);
+ shmdeque->push_back(IntType(i));
+ stddeque->push_back(i);
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ shmdeque->clear();
+ stddeque->clear();
+
+ for(int i = 0; i < max*50; ++i){
+ IntType move_me(i);
+ shmdeque->push_front(boost::move(move_me));
+ stddeque->push_front(i);
+ shmdeque->push_front(IntType(i));
+ stddeque->push_front(int(i));
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ typename MyShmDeque::iterator it;
+ typename MyShmDeque::const_iterator cit = it;
+ (void)cit;
+
+ shmdeque->erase(shmdeque->begin()++);
+ stddeque->erase(stddeque->begin()++);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ shmdeque->erase(shmdeque->begin());
+ stddeque->erase(stddeque->begin());
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ {
+ //Initialize values
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me (-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+
+ shmdeque->insert(shmdeque->end()
+ ,::boost::make_move_iterator(&aux_vect[0])
+ ,::boost::make_move_iterator(aux_vect + 50));
+ stddeque->insert(stddeque->end(), aux_vect2, aux_vect2 + 50);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ for(int i = 0, j = static_cast<int>(shmdeque->size()); i < j; ++i){
+ shmdeque->erase(shmdeque->begin());
+ stddeque->erase(stddeque->begin());
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+ }
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ shmdeque->insert(shmdeque->begin()
+ ,::boost::make_move_iterator(&aux_vect[0])
+ ,::boost::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
+ ,ipcdetail::bool_<!ipcdetail::is_same<IntType, test::movable_int>::value>())){
+ return false;
+ }
+
+ shmdeque->erase(shmdeque->begin());
+ stddeque->erase(stddeque->begin());
+
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ for(int i = 0; i < max; ++i){
+ IntType move_me(i);
+ shmdeque->insert(shmdeque->begin(), boost::move(move_me));
+ stddeque->insert(stddeque->begin(), i);
+ }
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return false;
+
+ //Test insertion from list
+ {
+ std::list<int> l(50, int(1));
+ shmdeque->insert(shmdeque->begin(), l.begin(), l.end());
+ stddeque->insert(stddeque->begin(), l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ shmdeque->assign(l.begin(), l.end());
+ stddeque->assign(l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+ }
+
+ shmdeque->resize(100);
+ stddeque->resize(100);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+
+ shmdeque->resize(200);
+ stddeque->resize(200);
+ if(!test::CheckEqualContainers(shmdeque, stddeque)) return 1;
+
+ segment.template destroy<MyShmDeque>("MyShmDeque");
+ delete stddeque;
+ segment.shrink_to_fit_indexes();
+
+ if(!segment.all_memory_deallocated())
+ return false;
+ }/*
+ catch(std::exception &ex){
+ std::cout << ex.what() << std::endl;
+ return false;
+ }*/
+
+ std::cout << std::endl << "Test OK!" << std::endl;
+ }/*
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }*/
+ shared_memory_object::remove(shMemName);
+ return true;
+}
+
+int main ()
+{
+ if(!do_test<int, allocator>())
+ return 1;
+
+ if(!do_test<test::movable_int, allocator>())
+ return 1;
+
+ if(!do_test<test::copyable_int, allocator>())
+ return 1;
+
+ if(!do_test<int, test::allocator_v1>())
+ return 1;
+
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
+
+ if(!boost::interprocess::test::test_emplace
+ < deque<test::EmplaceInt>, Options>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/dummy_test_allocator.hpp b/src/boost/libs/interprocess/test/dummy_test_allocator.hpp
new file mode 100644
index 000000000..42e5403ef
--- /dev/null
+++ b/src/boost/libs/interprocess/test/dummy_test_allocator.hpp
@@ -0,0 +1,149 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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_DUMMY_TEST_ALLOCATOR_HPP
+#define BOOST_INTERPROCESS_DUMMY_TEST_ALLOCATOR_HPP
+
+#if defined (_MSC_VER)
+# 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/containers/allocation_type.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <cstddef>
+
+//!\file
+//!Describes an allocator to test expand capabilities
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+//This allocator just allows two allocations. The first one will return
+//mp_buffer + m_offset configured in the constructor. The second one
+//will return mp_buffer.
+template<class T>
+class dummy_test_allocator
+{
+ private:
+ typedef dummy_test_allocator<T> self_t;
+ typedef void * aux_pointer_t;
+ typedef const void * cvoid_ptr;
+
+ template<class T2>
+ dummy_test_allocator& operator=(const dummy_test_allocator<T2>&);
+
+ dummy_test_allocator& operator=(const dummy_test_allocator&);
+
+ public:
+ typedef T value_type;
+ typedef T * pointer;
+ typedef const T * const_pointer;
+ typedef typename ipcdetail::add_reference
+ <value_type>::type reference;
+ typedef typename ipcdetail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+// typedef boost::interprocess::version_type<dummy_test_allocator, 2> version;
+
+ template<class T2>
+ struct rebind
+ { typedef dummy_test_allocator<T2> other; };
+
+ //!Default constructor. Never throws
+ dummy_test_allocator()
+ {}
+
+ //!Constructor from other dummy_test_allocator. Never throws
+ dummy_test_allocator(const dummy_test_allocator &)
+ {}
+
+ //!Constructor from related dummy_test_allocator. Never throws
+ template<class T2>
+ dummy_test_allocator(const dummy_test_allocator<T2> &)
+ {}
+
+ pointer address(reference value)
+ { return pointer(addressof(value)); }
+
+ const_pointer address(const_reference value) const
+ { return const_pointer(addressof(value)); }
+
+ pointer allocate(size_type, cvoid_ptr = 0)
+ { return 0; }
+
+ void deallocate(const pointer &, size_type)
+ { }
+
+ template<class Convertible>
+ void construct(pointer, const Convertible &)
+ {}
+
+ void destroy(pointer)
+ {}
+
+ size_type max_size() const
+ { return 0; }
+
+ friend void swap(self_t &, self_t &)
+ {}
+
+ //Experimental version 2 dummy_test_allocator functions
+
+ pointer allocation_command(boost::interprocess::allocation_type,
+ size_type, size_type &, pointer &)
+ { return pointer(); }
+
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold.
+ size_type size(const pointer &) const
+ { return 0; }
+
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one()
+ { return pointer(); }
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &)
+ {}
+};
+
+//!Equality test for same type of dummy_test_allocator
+template<class T> inline
+bool operator==(const dummy_test_allocator<T> &,
+ const dummy_test_allocator<T> &)
+{ return false; }
+
+//!Inequality test for same type of dummy_test_allocator
+template<class T> inline
+bool operator!=(const dummy_test_allocator<T> &,
+ const dummy_test_allocator<T> &)
+{ return true; }
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DUMMY_TEST_ALLOCATOR_HPP
+
diff --git a/src/boost/libs/interprocess/test/emplace_test.hpp b/src/boost/libs/interprocess/test/emplace_test.hpp
new file mode 100644
index 000000000..71cb2882a
--- /dev/null
+++ b/src/boost/libs/interprocess/test/emplace_test.hpp
@@ -0,0 +1,627 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2012. 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_TEST_EMPLACE_TEST_HPP
+#define BOOST_INTERPROCESS_TEST_EMPLACE_TEST_HPP
+
+#include <iostream>
+#include <typeinfo>
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/move/detail/type_traits.hpp> //make_unsigned, alignment_of
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+class EmplaceInt
+{
+ private:
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
+
+ public:
+ EmplaceInt()
+ : a_(0), b_(0), c_(0), d_(0), e_(0)
+ {}
+ EmplaceInt(int a, int b = 0, int c = 0, int d = 0, int e = 0)
+ : a_(a), b_(b), c_(c), d_(d), e_(e)
+ {}
+
+ EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
+ : a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
+ {}
+
+ EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
+ {
+ this->a_ = o.a_;
+ this->b_ = o.b_;
+ this->c_ = o.c_;
+ this->d_ = o.d_;
+ this->e_ = o.e_;
+ return *this;
+ }
+
+ friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
+ {
+ return l.a_ == r.a_ &&
+ l.b_ == r.b_ &&
+ l.c_ == r.c_ &&
+ l.d_ == r.d_ &&
+ l.e_ == r.e_;
+ }
+
+ friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
+ { return l.sum() < r.sum(); }
+
+ friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
+ { return l.sum() > r.sum(); }
+
+ friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
+ { return !(l == r); }
+
+ friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
+ {
+ os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
+ return os;
+ }
+
+ //private:
+ int sum() const
+ { return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
+
+ int a_, b_, c_, d_, e_;
+ int padding[6];
+};
+
+
+} //namespace test {
+
+namespace test {
+
+enum EmplaceOptions{
+ EMPLACE_BACK = 1 << 0,
+ EMPLACE_FRONT = 1 << 1,
+ EMPLACE_BEFORE = 1 << 2,
+ EMPLACE_AFTER = 1 << 3,
+ EMPLACE_ASSOC = 1 << 4,
+ EMPLACE_HINT = 1 << 5,
+ EMPLACE_ASSOC_PAIR = 1 << 6,
+ EMPLACE_HINT_PAIR = 1 << 7
+};
+
+template<class Container>
+bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n)
+{
+ typedef typename Container::const_iterator const_iterator;
+ const_iterator itb(ec.begin()), ite(ec.end());
+ unsigned int cur = 0;
+ if(only_first_n > ec.size()){
+ return false;
+ }
+ for(; itb != ite && only_first_n--; ++itb, ++cur){
+ const EmplaceInt & cr = *itb;
+ if(cr != Expected[cur]){
+ return false;
+ }
+ }
+ return true;
+}
+
+template<class Container>
+bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
+{
+ typedef typename Container::const_iterator const_iterator;
+ const_iterator itb(ec.begin()), ite(ec.end());
+ unsigned int cur = 0;
+ if(only_first_n > ec.size()){
+ return false;
+ }
+ for(; itb != ite && only_first_n--; ++itb, ++cur){
+ if(itb->first != Expected[cur].first){
+ std::cout << "Error in first: " << itb->first << ' ' << Expected[cur].first << std::endl;
+ return false;
+
+ }
+ else if(itb->second != Expected[cur].second){
+ std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+static EmplaceInt expected [10];
+
+typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
+static boost::container::dtl::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
+
+static EmplaceIntPair* initialize_emplace_int_pair()
+{
+ EmplaceIntPair* ret = reinterpret_cast<EmplaceIntPair*>(&pair_storage);
+ for(unsigned int i = 0; i != 10; ++i){
+ new(&ret->first)EmplaceInt();
+ new(&ret->second)EmplaceInt();
+ }
+ return ret;
+}
+
+static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
+
+
+template<class Container>
+bool test_emplace_back(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_back." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ {
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt(1, 2);
+ new(&expected [3]) EmplaceInt(1, 2, 3);
+ new(&expected [4]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
+ Container c;
+ c.emplace_back();
+ if(!test_expected_container(c, &expected[0], 1))
+ return false;
+ c.emplace_back(1);
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ c.emplace_back(1, 2);
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ c.emplace_back(1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 4))
+ return false;
+ c.emplace_back(1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 5))
+ return false;
+ c.emplace_back(1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ }
+
+ return true;
+}
+
+template<class Container>
+bool test_emplace_back(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_front(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_front." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ {
+ new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
+ new(&expected [1]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [2]) EmplaceInt(1, 2, 3);
+ new(&expected [3]) EmplaceInt(1, 2);
+ new(&expected [4]) EmplaceInt(1);
+ new(&expected [5]) EmplaceInt();
+ Container c;
+ c.emplace_front();
+ if(!test_expected_container(c, &expected[0] + 5, 1))
+ return false;
+ c.emplace_front(1);
+ if(!test_expected_container(c, &expected[0] + 4, 2))
+ return false;
+ c.emplace_front(1, 2);
+ if(!test_expected_container(c, &expected[0] + 3, 3))
+ return false;
+ c.emplace_front(1, 2, 3);
+ if(!test_expected_container(c, &expected[0] + 2, 4))
+ return false;
+ c.emplace_front(1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0] + 1, 5))
+ return false;
+ c.emplace_front(1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0] + 0, 6))
+ return false;
+ }
+ return true;
+}
+
+template<class Container>
+bool test_emplace_front(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_before(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_before." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ {
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt();
+ Container c;
+ c.emplace(c.cend(), 1);
+ c.emplace(c.cbegin());
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ c.emplace(c.cend());
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ }
+ {
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt(1, 2);
+ new(&expected [3]) EmplaceInt(1, 2, 3);
+ new(&expected [4]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
+ //emplace_front-like
+ Container c;
+ c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
+ c.emplace(c.cbegin(), 1, 2, 3, 4);
+ c.emplace(c.cbegin(), 1, 2, 3);
+ c.emplace(c.cbegin(), 1, 2);
+ c.emplace(c.cbegin(), 1);
+ c.emplace(c.cbegin());
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ c.clear();
+ //emplace_back-like
+ typename Container::const_iterator i = c.emplace(c.cend());
+ if(!test_expected_container(c, &expected[0], 1))
+ return false;
+ i = c.emplace(++i, 1);
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ i = c.emplace(++i, 1, 2);
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ i = c.emplace(++i, 1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 4))
+ return false;
+ i = c.emplace(++i, 1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 5))
+ return false;
+ i = c.emplace(++i, 1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ c.clear();
+ //emplace in the middle
+ c.emplace(c.cbegin());
+ i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
+ i = c.emplace(i, 1, 2, 3, 4);
+ i = c.emplace(i, 1, 2, 3);
+ i = c.emplace(i, 1, 2);
+ i = c.emplace(i, 1);
+
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ }
+ return true;
+}
+
+template<class Container>
+bool test_emplace_before(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_after(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_after." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+ {
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt();
+ Container c;
+ typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
+ c.emplace_after(c.cbefore_begin());
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ c.emplace_after(i);
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ }
+ {
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt(1, 2);
+ new(&expected [3]) EmplaceInt(1, 2, 3);
+ new(&expected [4]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
+ //emplace_front-like
+ Container c;
+ c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4, 5);
+ c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4);
+ c.emplace_after(c.cbefore_begin(), 1, 2, 3);
+ c.emplace_after(c.cbefore_begin(), 1, 2);
+ c.emplace_after(c.cbefore_begin(), 1);
+ c.emplace_after(c.cbefore_begin());
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ c.clear();
+ //emplace_back-like
+ typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
+ if(!test_expected_container(c, &expected[0], 1))
+ return false;
+ i = c.emplace_after(i, 1);
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ i = c.emplace_after(i, 1, 2);
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ i = c.emplace_after(i, 1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 4))
+ return false;
+ i = c.emplace_after(i, 1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 5))
+ return false;
+ i = c.emplace_after(i, 1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ c.clear();
+ //emplace_after in the middle
+ i = c.emplace_after(c.cbefore_begin());
+ c.emplace_after(i, 1, 2, 3, 4, 5);
+ c.emplace_after(i, 1, 2, 3, 4);
+ c.emplace_after(i, 1, 2, 3);
+ c.emplace_after(i, 1, 2);
+ c.emplace_after(i, 1);
+
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ }
+ return true;
+}
+
+template<class Container>
+bool test_emplace_after(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_assoc(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt(1, 2);
+ new(&expected [3]) EmplaceInt(1, 2, 3);
+ new(&expected [4]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
+ {
+ Container c;
+ c.emplace();
+ if(!test_expected_container(c, &expected[0], 1))
+ return false;
+ c.emplace(1);
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ c.emplace(1, 2);
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ c.emplace(1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 4))
+ return false;
+ c.emplace(1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 5))
+ return false;
+ c.emplace(1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ }
+ return true;
+}
+
+template<class Container>
+bool test_emplace_assoc(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_hint(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt(1, 2);
+ new(&expected [3]) EmplaceInt(1, 2, 3);
+ new(&expected [4]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
+
+ {
+ Container c;
+ typename Container::const_iterator it;
+ it = c.emplace_hint(c.begin());
+ if(!test_expected_container(c, &expected[0], 1))
+ return false;
+ it = c.emplace_hint(it, 1);
+ if(!test_expected_container(c, &expected[0], 2))
+ return false;
+ it = c.emplace_hint(it, 1, 2);
+ if(!test_expected_container(c, &expected[0], 3))
+ return false;
+ it = c.emplace_hint(it, 1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 4))
+ return false;
+ it = c.emplace_hint(it, 1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 5))
+ return false;
+ it = c.emplace_hint(it, 1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 6))
+ return false;
+ }
+
+ return true;
+}
+
+template<class Container>
+bool test_emplace_hint(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_assoc_pair(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ new(&expected_pair[0].first) EmplaceInt();
+ new(&expected_pair[0].second) EmplaceInt();
+ new(&expected_pair[1].first) EmplaceInt(1);
+ new(&expected_pair[1].second) EmplaceInt();
+ new(&expected_pair[2].first) EmplaceInt(2);
+ new(&expected_pair[2].second) EmplaceInt(2);
+// new(&expected_pair[3].first) EmplaceInt(3);
+// new(&expected_pair[3].second) EmplaceInt(2, 3);
+// new(&expected_pair[4].first) EmplaceInt(4);
+// new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
+// new(&expected_pair[5].first) EmplaceInt(5);
+// new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
+ { //piecewise construct missing
+ /*
+ Container c;
+ c.emplace();
+ if(!test_expected_container(c, &expected_pair[0], 1)){
+ std::cout << "Error after c.emplace();\n";
+ return false;
+ }
+ c.emplace(1);
+ if(!test_expected_container(c, &expected_pair[0], 2)){
+ std::cout << "Error after c.emplace(1);\n";
+ return false;
+ }
+ c.emplace(2, 2);
+ if(!test_expected_container(c, &expected_pair[0], 3)){
+ std::cout << "Error after c.emplace(2, 2);\n";
+ return false;
+ }
+ c.emplace(3, 2, 3);
+ if(!test_expected_container(c, &expected_pair[0], 4)){
+ std::cout << "Error after c.emplace(3, 2, 3);\n";
+ return false;
+ }
+ c.emplace(4, 2, 3, 4);
+ if(!test_expected_container(c, &expected_pair[0], 5)){
+ std::cout << "Error after c.emplace(4, 2, 3, 4);\n";
+ return false;
+ }
+ c.emplace(5, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected_pair[0], 6)){
+ std::cout << "Error after c.emplace(5, 2, 3, 4, 5);\n";
+ return false;
+ }*/
+ }
+ return true;
+}
+
+template<class Container>
+bool test_emplace_assoc_pair(ipcdetail::false_)
+{ return true; }
+
+template<class Container>
+bool test_emplace_hint_pair(ipcdetail::true_)
+{
+ std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
+ << typeid(Container).name() << std::endl;
+
+ new(&expected_pair[0].first) EmplaceInt();
+ new(&expected_pair[0].second) EmplaceInt();
+ new(&expected_pair[1].first) EmplaceInt(1);
+ new(&expected_pair[1].second) EmplaceInt();
+ new(&expected_pair[2].first) EmplaceInt(2);
+ new(&expected_pair[2].second) EmplaceInt(2);/*
+ new(&expected_pair[3].first) EmplaceInt(3);
+ new(&expected_pair[3].second) EmplaceInt(2, 3);
+ new(&expected_pair[4].first) EmplaceInt(4);
+ new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
+ new(&expected_pair[5].first) EmplaceInt(5);
+ new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);*/
+ {/*
+ Container c;
+ typename Container::const_iterator it;
+ it = c.emplace_hint(c.begin());
+ if(!test_expected_container(c, &expected_pair[0], 1)){
+ std::cout << "Error after c.emplace(1);\n";
+ return false;
+ }
+ it = c.emplace_hint(it, 1);
+ if(!test_expected_container(c, &expected_pair[0], 2)){
+ std::cout << "Error after c.emplace(it, 1);\n";
+ return false;
+ }
+ it = c.emplace_hint(it, 2, 2);
+ if(!test_expected_container(c, &expected_pair[0], 3)){
+ std::cout << "Error after c.emplace(it, 2, 2);\n";
+ return false;
+ }
+ it = c.emplace_hint(it, 3, 2, 3);
+ if(!test_expected_container(c, &expected_pair[0], 4)){
+ std::cout << "Error after c.emplace(it, 3, 2, 3);\n";
+ return false;
+ }
+ it = c.emplace_hint(it, 4, 2, 3, 4);
+ if(!test_expected_container(c, &expected_pair[0], 5)){
+ std::cout << "Error after c.emplace(it, 4, 2, 3, 4);\n";
+ return false;
+ }
+ it = c.emplace_hint(it, 5, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected_pair[0], 6)){
+ std::cout << "Error after c.emplace(it, 5, 2, 3, 4, 5);\n";
+ return false;
+ }*/
+ }
+ return true;
+}
+
+template<class Container>
+bool test_emplace_hint_pair(ipcdetail::false_)
+{ return true; }
+
+template <EmplaceOptions O, EmplaceOptions Mask>
+struct emplace_active
+{
+ static const bool value = (0 != (O & Mask));
+ typedef ipcdetail::bool_<value> type;
+ operator type() const{ return type(); }
+};
+
+template<class Container, EmplaceOptions O>
+bool test_emplace()
+{
+ if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>()))
+ return false;
+ if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>()))
+ return false;
+ if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>()))
+ return false;
+ if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>()))
+ return false;
+ if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>()))
+ return false;
+ if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>()))
+ return false;
+ if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>()))
+ return false;
+ if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>()))
+ return false;
+ return true;
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_EMPLACE_TEST_HPP
diff --git a/src/boost/libs/interprocess/test/enable_shared_from_this_test.cpp b/src/boost/libs/interprocess/test/enable_shared_from_this_test.cpp
new file mode 100644
index 000000000..342e0a7ed
--- /dev/null
+++ b/src/boost/libs/interprocess/test/enable_shared_from_this_test.cpp
@@ -0,0 +1,97 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2002, 2003 Peter Dimov
+//
+// This file is the adaptation of shared_from_this_test.cpp from smart_ptr library
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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>
+#include <boost/interprocess/smart_ptr/enable_shared_from_this.hpp>
+#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include "get_process_id_name.hpp"
+
+//
+
+using namespace boost::interprocess;
+
+typedef allocator<void, managed_shared_memory::segment_manager>
+ v_allocator_t;
+
+struct X;
+
+typedef deleter<X, managed_shared_memory::segment_manager> x_deleter_t;
+
+struct X :
+ public enable_shared_from_this<X, v_allocator_t, x_deleter_t>
+{
+};
+
+typedef shared_ptr<X, v_allocator_t, x_deleter_t> v_shared_ptr;
+
+
+template<class ManagedMemory>
+void test_enable_shared_this(ManagedMemory &managed_mem)
+{
+ v_shared_ptr p(make_managed_shared_ptr
+ (managed_mem.template construct<X>(anonymous_instance)(), managed_mem));
+
+ v_shared_ptr q = p->shared_from_this();
+ BOOST_TEST(p == q);
+ BOOST_TEST(!(p < q) && !(q < p));
+
+ X v2(*p);
+
+ try
+ {
+ //This should throw bad_weak_ptr
+ v_shared_ptr r = v2.shared_from_this();
+ BOOST_ERROR("v2.shared_from_this() failed to throw");
+ }
+ catch(boost::interprocess::bad_weak_ptr const &)
+ {
+ //This is the expected path
+ }
+ catch(...){
+ BOOST_ERROR("v2.shared_from_this() threw an unexpected exception");
+ }
+
+ try
+ {
+ //This should not throw bad_weak_ptr
+ *p = X();
+ v_shared_ptr r = p->shared_from_this();
+ BOOST_TEST(p == r);
+ BOOST_TEST(!(p < r) && !(r < p));
+ }
+ catch(boost::interprocess::bad_weak_ptr const &)
+ {
+ BOOST_ERROR("p->shared_from_this() threw bad_weak_ptr after *p = X()");
+ }
+ catch(...)
+ {
+ BOOST_ERROR("p->shared_from_this() threw an unexpected exception after *p = X()");
+ }
+}
+
+
+int main()
+{
+ std::string process_name;
+ test::get_process_id_name(process_name);
+ shared_memory_object::remove(process_name.c_str());
+ managed_shared_memory shmem(create_only, process_name.c_str(), 65536);
+ test_enable_shared_this(shmem);
+ shared_memory_object::remove(process_name.c_str());
+ return boost::report_errors();
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/expand_bwd_test_allocator.hpp b/src/boost/libs/interprocess/test/expand_bwd_test_allocator.hpp
new file mode 100644
index 000000000..7124c5743
--- /dev/null
+++ b/src/boost/libs/interprocess/test/expand_bwd_test_allocator.hpp
@@ -0,0 +1,193 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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_EXPAND_BWD_TEST_ALLOCATOR_HPP
+#define BOOST_INTERPROCESS_EXPAND_BWD_TEST_ALLOCATOR_HPP
+
+#if defined (_MSC_VER)
+# 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/containers/allocation_type.hpp>
+#include <boost/assert.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <memory>
+#include <cstddef>
+#include <cassert>
+#include <new>
+
+//!\file
+//!Describes an allocator to test expand capabilities
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+//This allocator just allows two allocations. The first one will return
+//mp_buffer + m_offset configured in the constructor. The second one
+//will return mp_buffer.
+template<class T>
+class expand_bwd_test_allocator
+{
+ private:
+ typedef expand_bwd_test_allocator<T> self_t;
+ typedef void * aux_pointer_t;
+ typedef const void * cvoid_ptr;
+
+ template<class T2>
+ expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
+
+ expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
+
+ public:
+ typedef T value_type;
+ typedef T * pointer;
+ typedef const T * const_pointer;
+ typedef typename ipcdetail::add_reference
+ <value_type>::type reference;
+ typedef typename ipcdetail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef boost::interprocess::version_type<expand_bwd_test_allocator, 2> version;
+
+ //Dummy multiallocation chain
+ struct multiallocation_chain{};
+
+ template<class T2>
+ struct rebind
+ { typedef expand_bwd_test_allocator<T2> other; };
+
+ //!Constructor from the segment manager. Never throws
+ expand_bwd_test_allocator(T *buf, size_type sz, difference_type offset)
+ : mp_buffer(buf), m_size(sz)
+ , m_offset(offset), m_allocations(0){ }
+
+ //!Constructor from other expand_bwd_test_allocator. Never throws
+ expand_bwd_test_allocator(const expand_bwd_test_allocator &other)
+ : mp_buffer(other.mp_buffer), m_size(other.m_size)
+ , m_offset(other.m_offset), m_allocations(0){ }
+
+ //!Constructor from related expand_bwd_test_allocator. Never throws
+ template<class T2>
+ expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
+ : mp_buffer(other.mp_buffer), m_size(other.m_size)
+ , m_offset(other.m_offset), m_allocations(0){ }
+
+ pointer address(reference value)
+ { return pointer(addressof(value)); }
+
+ const_pointer address(const_reference value) const
+ { return const_pointer(addressof(value)); }
+
+ pointer allocate(size_type , cvoid_ptr hint = 0)
+ { (void)hint; return 0; }
+
+ void deallocate(const pointer &, size_type)
+ {}
+
+ template<class Convertible>
+ void construct(pointer ptr, const Convertible &value)
+ { new((void*)ptr) value_type(value); }
+
+ void destroy(pointer ptr)
+ { (*ptr).~value_type(); }
+
+ size_type max_size() const
+ { return m_size; }
+
+ friend void swap(self_t &alloc1, self_t &alloc2)
+ {
+ ::boost::adl_move_swap(alloc1.mp_buffer, alloc2.mp_buffer);
+ ::boost::adl_move_swap(alloc1.m_size, alloc2.m_size);
+ ::boost::adl_move_swap(alloc1.m_offset, alloc2.m_offset);
+ }
+
+ //Experimental version 2 expand_bwd_test_allocator functions
+
+ pointer allocation_command(boost::interprocess::allocation_type command,
+ size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
+ {
+ (void)reuse; (void)command;
+ //This allocator only expands backwards!
+ assert(m_allocations == 0 || (command & boost::interprocess::expand_bwd));
+ prefer_in_recvd_out_size = limit_size;
+
+ if(m_allocations == 0){
+ if((m_offset + limit_size) > m_size){
+ assert(0);
+ }
+ ++m_allocations;
+ return mp_buffer + m_offset;
+ }
+ else if(m_allocations == 1){
+ if(limit_size > m_size){
+ assert(0);
+ }
+ ++m_allocations;
+ return mp_buffer;
+ }
+ else{
+ assert(0);
+ throw std::bad_alloc();
+ }
+ }
+
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold.
+ size_type size(const pointer &p) const
+ { (void)p; return m_size; }
+
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one()
+ { return this->allocate(1); }
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p)
+ { return this->deallocate(p, 1); }
+
+ pointer mp_buffer;
+ size_type m_size;
+ difference_type m_offset;
+ char m_allocations;
+};
+
+//!Equality test for same type of expand_bwd_test_allocator
+template<class T> inline
+bool operator==(const expand_bwd_test_allocator<T> &,
+ const expand_bwd_test_allocator<T> &)
+{ return false; }
+
+//!Inequality test for same type of expand_bwd_test_allocator
+template<class T> inline
+bool operator!=(const expand_bwd_test_allocator<T> &,
+ const expand_bwd_test_allocator<T> &)
+{ return true; }
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_EXPAND_BWD_TEST_ALLOCATOR_HPP
+
diff --git a/src/boost/libs/interprocess/test/expand_bwd_test_template.hpp b/src/boost/libs/interprocess/test/expand_bwd_test_template.hpp
new file mode 100644
index 000000000..91d1146b9
--- /dev/null
+++ b/src/boost/libs/interprocess/test/expand_bwd_test_template.hpp
@@ -0,0 +1,269 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
+#define BOOST_INTERPROCESS_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include "expand_bwd_test_allocator.hpp"
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <algorithm> //std::equal
+#include <vector>
+#include <iostream>
+
+namespace boost { namespace interprocess { namespace test {
+
+template<class T>
+struct value_holder
+{
+ value_holder(T val) : m_value(val){}
+ value_holder(): m_value(0){}
+ ~value_holder(){ m_value = 0; }
+ bool operator == (const value_holder &other) const
+ { return m_value == other.m_value; }
+ bool operator != (const value_holder &other) const
+ { return m_value != other.m_value; }
+
+ T m_value;
+};
+
+template<class T>
+struct triple_value_holder
+{
+ triple_value_holder(T val)
+ : m_value1(val)
+ , m_value2(val)
+ , m_value3(val)
+ {}
+
+ triple_value_holder()
+ : m_value1(0)
+ , m_value2(0)
+ , m_value3(0)
+ {}
+
+ ~triple_value_holder()
+ { m_value1 = m_value2 = m_value3 = 0; }
+
+ bool operator == (const triple_value_holder &other) const
+ {
+ return m_value1 == other.m_value1
+ && m_value2 == other.m_value2
+ && m_value3 == other.m_value3;
+ }
+
+ bool operator != (const triple_value_holder &other) const
+ {
+ return m_value1 != other.m_value1
+ || m_value2 != other.m_value2
+ || m_value3 != other.m_value3;
+ }
+
+ T m_value1;
+ T m_value2;
+ T m_value3;
+};
+
+typedef value_holder<int> int_holder;
+typedef triple_value_holder<int> triple_int_holder;
+
+
+
+//Function to check if both sets are equal
+template <class Vector1, class Vector2>
+bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
+{
+ if(vector1.size() != vector2.size())
+ return false;
+ return std::equal(vector1.begin(), vector1.end(), vector2.begin());
+}
+
+template<class Vector>
+bool CheckUninitializedIsZero(const Vector & v)
+{
+ typedef typename Vector::value_type value_type;
+ typename Vector::size_type sz = v.size();
+ typename Vector::size_type extra = v.capacity() - v.size();
+ value_type comp(0);
+
+ const value_type *holder = &v[0] + sz;
+
+ while(extra--){
+ if(*holder++ != comp)
+ return false;
+ }
+ return true;
+}
+
+
+//This function tests all the possible combinations when
+//inserting data in a vector and expanding backwards
+template<class VectorWithExpandBwdAllocator>
+bool test_insert_with_expand_bwd()
+{
+ typedef typename VectorWithExpandBwdAllocator::value_type value_type;
+ typedef typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type non_volatile_value_type;
+ typedef std::vector<non_volatile_value_type> Vect;
+ const int MemorySize = 1000;
+
+ //Distance old and new buffer
+ const int Offset[] =
+ { 350, 250, 150, 150,
+ 150, 50, 50, 50 };
+ //Insert position
+ const int Position[] =
+ { 100, 100, 100, 100,
+ 100, 100, 100, 100 };
+ //Initial vector size
+ const int InitialSize[] =
+ { 200, 200, 200, 200,
+ 200, 200, 200, 200 };
+ //Size of the data to insert
+ const int InsertSize[] =
+ { 100, 100, 100, 200,
+ 300, 25, 100, 200 };
+ //Number of tests
+ const int Iterations = sizeof(InsertSize)/sizeof(int);
+
+ for(int iteration = 0; iteration < Iterations; ++iteration)
+ {
+ value_type *memory = new value_type[MemorySize];
+ try {
+ std::vector<non_volatile_value_type> initial_data;
+ initial_data.resize(InitialSize[iteration]);
+ for(int i = 0; i < InitialSize[iteration]; ++i){
+ initial_data[i] = i;
+ }
+
+ Vect data_to_insert;
+ data_to_insert.resize(InsertSize[iteration]);
+ for(int i = 0; i < InsertSize[iteration]; ++i){
+ data_to_insert[i] = -i;
+ }
+
+ expand_bwd_test_allocator<value_type> alloc
+ (&memory[0], MemorySize, Offset[iteration]);
+ VectorWithExpandBwdAllocator vector(alloc);
+ vector.insert( vector.begin()
+ , initial_data.begin(), initial_data.end());
+ vector.insert( vector.begin() + Position[iteration]
+ , data_to_insert.begin(), data_to_insert.end());
+ initial_data.insert(initial_data.begin() + Position[iteration]
+ , data_to_insert.begin(), data_to_insert.end());
+ //Now check that values are equal
+ if(!CheckEqualVector(vector, initial_data)){
+ std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
+ << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
+ << " Iteration: " << iteration << std::endl;
+ return false;
+ }
+ }
+ catch(...){
+ delete [](const_cast<non_volatile_value_type*>(memory));
+ throw;
+ }
+ delete [](const_cast<non_volatile_value_type*>(memory));
+ }
+
+ return true;
+}
+
+//This function tests all the possible combinations when
+//inserting data in a vector and expanding backwards
+template<class VectorWithExpandBwdAllocator>
+bool test_assign_with_expand_bwd()
+{
+ typedef typename VectorWithExpandBwdAllocator::value_type value_type;
+ typedef typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type non_volatile_value_type;
+ const int MemorySize = 200;
+
+ const int Offset[] = { 50, 50, 50};
+ const int InitialSize[] = { 25, 25, 25};
+ const int InsertSize[] = { 15, 35, 55};
+ const int Iterations = sizeof(InsertSize)/sizeof(int);
+
+ for(int iteration = 0; iteration <Iterations; ++iteration)
+ {
+ value_type *memory = new value_type[MemorySize];
+ try {
+ //Create initial data
+ std::vector<non_volatile_value_type> initial_data;
+ initial_data.resize(InitialSize[iteration]);
+ for(int i = 0; i < InitialSize[iteration]; ++i){
+ initial_data[i] = i;
+ }
+
+ //Create data to insert
+ std::vector<non_volatile_value_type> data_to_insert;
+ data_to_insert.resize(InsertSize[iteration]);
+ for(int i = 0; i < InsertSize[iteration]; ++i){
+ data_to_insert[i] = -i;
+ }
+
+ //Insert initial data to the vector to test
+ expand_bwd_test_allocator<value_type> alloc
+ (&memory[0], MemorySize, Offset[iteration]);
+ VectorWithExpandBwdAllocator vector(alloc);
+ vector.insert( vector.begin()
+ , initial_data.begin(), initial_data.end());
+
+ //Insert data
+ vector.insert(vector.cbegin(), data_to_insert.begin(), data_to_insert.end());
+ initial_data.insert(initial_data.begin(), data_to_insert.begin(), data_to_insert.end());
+
+ //Now check that values are equal
+ if(!CheckEqualVector(vector, initial_data)){
+ std::cout << "test_insert_with_expand_bwd::CheckEqualVector failed." << std::endl
+ << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
+ << " Iteration: " << iteration << std::endl;
+ return false;
+ }
+ }
+ catch(...){
+ delete [](const_cast<typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type*>(memory));
+ throw;
+ }
+ delete [](const_cast<typename boost::interprocess::ipcdetail::remove_volatile<value_type>::type*>(memory));
+ }
+
+ return true;
+}
+
+//This function calls all tests
+template<class VectorWithExpandBwdAllocator>
+bool test_all_expand_bwd()
+{
+ std::cout << "Starting test_insert_with_expand_bwd." << std::endl << " Class: "
+ << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
+
+ if(!test_insert_with_expand_bwd<VectorWithExpandBwdAllocator>()){
+ std::cout << "test_allocation_direct_deallocation failed. Class: "
+ << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_assign_with_expand_bwd." << std::endl << " Class: "
+ << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
+
+ if(!test_assign_with_expand_bwd<VectorWithExpandBwdAllocator>()){
+ std::cout << "test_allocation_direct_deallocation failed. Class: "
+ << typeid(VectorWithExpandBwdAllocator).name() << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_TEST_ALLOCATION_TEST_TEMPLATE_HEADER
+
diff --git a/src/boost/libs/interprocess/test/file_lock_test.cpp b/src/boost/libs/interprocess/test/file_lock_test.cpp
new file mode 100644
index 000000000..6dcfd9260
--- /dev/null
+++ b/src/boost/libs/interprocess/test/file_lock_test.cpp
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+#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> //std::remove
+
+using namespace boost::interprocess;
+
+inline std::string get_filename()
+{
+ std::string ret (ipcdetail::get_temporary_path());
+ ret += "/";
+ ret += test::get_process_id_name();
+ return ret;
+}
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class file_lock_lock_test_wrapper
+ : public boost::interprocess::file_lock
+{
+ public:
+ file_lock_lock_test_wrapper()
+ : boost::interprocess::file_lock(get_filename().c_str())
+ {}
+};
+
+int main ()
+{
+ //Destroy and create file
+ {
+ std::remove(get_filename().c_str());
+ std::ofstream file(get_filename().c_str());
+ if(!file){
+ return 1;
+ }
+ file_lock flock(get_filename().c_str());
+ {
+ scoped_lock<file_lock> sl(flock);
+ }
+ {
+ scoped_lock<file_lock> sl(flock, try_to_lock);
+ }
+ {
+ scoped_lock<file_lock> sl(flock, test::delay(1));
+ }
+ }
+ {
+ //Now test move semantics
+ file_lock mapping(get_filename().c_str());
+ file_lock move_ctor(boost::move(mapping));
+ file_lock move_assign;
+ move_assign = boost::move(move_ctor);
+ mapping.swap(move_assign);
+ }
+
+ //test::test_all_lock<file_lock_lock_test_wrapper>();
+ //test::test_all_mutex<file_lock_lock_test_wrapper>();
+ //test::test_all_sharable_mutex<file_lock_lock_test_wrapper>();
+ std::remove(get_filename().c_str());
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/file_mapping_test.cpp b/src/boost/libs/interprocess/test/file_mapping_test.cpp
new file mode 100644
index 000000000..c3ce16147
--- /dev/null
+++ b/src/boost/libs/interprocess/test/file_mapping_test.cpp
@@ -0,0 +1,164 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <ios> //std::streamoff
+#include <fstream> //std::ofstream, std::ifstream
+#include <iostream>
+#include <boost/interprocess/file_mapping.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/container/vector.hpp>
+#include <stdexcept> //std::exception
+#include <cstddef> //std::size_t
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+inline std::string get_filename()
+{
+ std::string ret (ipcdetail::get_temporary_path());
+ ret += "/";
+ ret += test::get_process_id_name();
+ return ret;
+}
+
+file_mapping get_file_mapping()
+{
+ file_mapping f;
+ return file_mapping(boost::move(f));
+}
+
+int main ()
+{
+ try{
+ const std::size_t FileSize = 99999*2;
+ {
+ //Create file with given size
+ std::ofstream file(get_filename().c_str(), std::ios::binary | std::ios::trunc);
+ file.seekp(static_cast<std::streamoff>(FileSize-1));
+ file.write("", 1);
+ }
+
+ {
+ //Create a file mapping
+ file_mapping mapping(get_filename().c_str(), read_write);
+ //Create two mapped regions, one half of the file each
+ mapped_region region (mapping
+ ,read_write
+ ,0
+ ,FileSize/2
+ );
+
+ mapped_region region2(mapping
+ ,read_write
+ ,FileSize/2
+ ,FileSize - FileSize/2
+ );
+
+ //Fill two regions with a pattern
+ unsigned char *filler = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+
+ filler = static_cast<unsigned char*>(region2.get_address());
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+ if(!region.flush(0, 0, false)){
+ return 1;
+ }
+
+ if(!region2.flush(0, 0, true)){
+ return 1;
+ }
+ }
+
+ //See if the pattern is correct in the file
+ {
+ //Open the file
+ std::ifstream file(get_filename().c_str(), std::ios::binary);
+
+ //Create a memory buffer
+ boost::container::vector<unsigned char> memory(FileSize/2 +1);
+
+ //Fill buffer
+ file.read(static_cast<char*>(static_cast<void*>(memory.data()))
+ , FileSize/2);
+
+ unsigned char *checker = memory.data();
+ //Check pattern
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+
+ //Fill buffer
+ file.read(static_cast<char*>(static_cast<void*>(memory.data()))
+ , FileSize - FileSize/2);
+
+ checker = memory.data();
+ //Check pattern
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+
+ //Now check the pattern mapping a single read only mapped_region
+ {
+ //Create a file mapping
+ file_mapping mapping(get_filename().c_str(), read_only);
+
+ //Create a single regions, mapping all the file
+ mapped_region region (mapping
+ ,read_only
+ );
+
+ //Check pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+ {
+ //Now test move semantics
+ file_mapping mapping(get_filename().c_str(), read_only);
+ file_mapping move_ctor(boost::move(mapping));
+ file_mapping move_assign;
+ move_assign = boost::move(move_ctor);
+ mapping.swap(move_assign);
+ file_mapping ret(get_file_mapping());
+ }
+ }
+ catch(std::exception &exc){
+ file_mapping::remove(get_filename().c_str());
+ std::cout << "Unhandled exception: " << exc.what() << std::endl;
+ throw;
+ }
+ file_mapping::remove(get_filename().c_str());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/flat_map_index_allocation_test.cpp b/src/boost/libs/interprocess/test/flat_map_index_allocation_test.cpp
new file mode 100644
index 000000000..41476ab3d
--- /dev/null
+++ b/src/boost/libs/interprocess/test/flat_map_index_allocation_test.cpp
@@ -0,0 +1,25 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/indexes/flat_map_index.hpp>
+#include "named_allocation_test_template.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+ if(!test::test_named_allocation<flat_map_index>()){
+ return 1;
+ }
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/flat_tree_test.cpp b/src/boost/libs/interprocess/test/flat_tree_test.cpp
new file mode 100644
index 000000000..bd4af0f78
--- /dev/null
+++ b/src/boost/libs/interprocess/test/flat_tree_test.cpp
@@ -0,0 +1,202 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <set>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/flat_set.hpp>
+#include <boost/interprocess/containers/flat_map.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/indexes/flat_map_index.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "set_test.hpp"
+#include "map_test.hpp"
+#include "emplace_test.hpp"
+
+/////////////////////////////////////////////////////////////////
+//
+// This example repeats the same operations with std::set and
+// shmem_set using the node allocator
+// and compares the values of both containers
+//
+/////////////////////////////////////////////////////////////////
+
+using namespace boost::interprocess;
+
+//Customize managed_shared_memory class
+typedef basic_managed_shared_memory
+ <char,
+ //simple_seq_fit<mutex_family>,
+ rbtree_best_fit<mutex_family>,
+ iset_index
+ > my_managed_shared_memory;
+
+//Alias allocator type
+typedef allocator<int, my_managed_shared_memory::segment_manager>
+ shmem_allocator_t;
+typedef allocator<test::movable_int, my_managed_shared_memory::segment_manager>
+ shmem_movable_allocator_t;
+typedef allocator<std::pair<int, int>, my_managed_shared_memory::segment_manager>
+ shmem_pair_allocator_t;
+typedef allocator<std::pair<test::movable_int, test::movable_int>, my_managed_shared_memory::segment_manager>
+ shmem_movable_pair_allocator_t;
+
+typedef allocator<test::movable_and_copyable_int, my_managed_shared_memory::segment_manager>
+ shmem_move_copy_allocator_t;
+
+typedef allocator<test::copyable_int, my_managed_shared_memory::segment_manager>
+ shmem_copy_allocator_t;
+
+typedef allocator<std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int>, my_managed_shared_memory::segment_manager>
+ shmem_move_copy_pair_allocator_t;
+
+//Alias set types
+typedef std::set<int> MyStdSet;
+typedef std::multiset<int> MyStdMultiSet;
+typedef std::map<int, int> MyStdMap;
+typedef std::multimap<int, int> MyStdMultiMap;
+
+typedef flat_set<int, std::less<int>, shmem_allocator_t> MyShmSet;
+typedef flat_multiset<int, std::less<int>, shmem_allocator_t> MyShmMultiSet;
+typedef flat_map<int, int, std::less<int>, shmem_pair_allocator_t> MyShmMap;
+typedef flat_multimap<int, int, std::less<int>, shmem_pair_allocator_t> MyShmMultiMap;
+
+typedef flat_set<test::movable_int, std::less<test::movable_int>
+ ,shmem_movable_allocator_t> MyMovableShmSet;
+typedef flat_multiset<test::movable_int,std::less<test::movable_int>
+ ,shmem_movable_allocator_t> MyMovableShmMultiSet;
+typedef flat_map<test::movable_int, test::movable_int
+ ,std::less<test::movable_int>
+ ,shmem_movable_pair_allocator_t> MyMovableShmMap;
+typedef flat_multimap<test::movable_int, test::movable_int
+ ,std::less<test::movable_int>
+ ,shmem_movable_pair_allocator_t> MyMovableShmMultiMap;
+
+typedef flat_set<test::movable_and_copyable_int, std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_allocator_t> MyMoveCopyShmSet;
+typedef flat_multiset<test::movable_and_copyable_int,std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_allocator_t> MyMoveCopyShmMultiSet;
+
+typedef flat_set<test::copyable_int, std::less<test::copyable_int>
+ ,shmem_copy_allocator_t> MyCopyShmSet;
+typedef flat_multiset<test::copyable_int,std::less<test::copyable_int>
+ ,shmem_copy_allocator_t> MyCopyShmMultiSet;
+
+typedef flat_map<test::movable_and_copyable_int, test::movable_and_copyable_int
+ ,std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_pair_allocator_t> MyMoveCopyShmMap;
+typedef flat_multimap<test::movable_and_copyable_int, test::movable_and_copyable_int
+ ,std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_pair_allocator_t> MyMoveCopyShmMultiMap;
+
+int main()
+{
+ using namespace boost::interprocess::test;
+
+ if (0 != set_test<my_managed_shared_memory
+ ,MyShmSet
+ ,MyStdSet
+ ,MyShmMultiSet
+ ,MyStdMultiSet>()){
+ std::cout << "Error in set_test<MyShmSet>" << std::endl;
+ return 1;
+ }
+
+ if (0 != set_test_copyable<my_managed_shared_memory
+ ,MyShmSet
+ ,MyStdSet
+ ,MyShmMultiSet
+ ,MyStdMultiSet>()){
+ std::cout << "Error in set_test<MyShmSet>" << std::endl;
+ return 1;
+ }
+
+ if (0 != set_test<my_managed_shared_memory
+ ,MyMovableShmSet
+ ,MyStdSet
+ ,MyMovableShmMultiSet
+ ,MyStdMultiSet>()){
+ std::cout << "Error in set_test<MyMovableShmSet>" << std::endl;
+ return 1;
+ }
+
+ if (0 != set_test<my_managed_shared_memory
+ ,MyMoveCopyShmSet
+ ,MyStdSet
+ ,MyMoveCopyShmMultiSet
+ ,MyStdMultiSet>()){
+ std::cout << "Error in set_test<MyMoveCopyShmSet>" << std::endl;
+ return 1;
+ }
+
+ if (0 != set_test<my_managed_shared_memory
+ ,MyCopyShmSet
+ ,MyStdSet
+ ,MyCopyShmMultiSet
+ ,MyStdMultiSet>()){
+ std::cout << "Error in set_test<MyCopyShmSet>" << std::endl;
+ return 1;
+ }
+
+ if (0 != map_test<my_managed_shared_memory
+ ,MyShmMap
+ ,MyStdMap
+ ,MyShmMultiMap
+ ,MyStdMultiMap>()){
+ std::cout << "Error in map_test<MyShmMap>" << std::endl;
+ return 1;
+ }
+
+ if (0 != map_test_copyable<my_managed_shared_memory
+ ,MyShmMap
+ ,MyStdMap
+ ,MyShmMultiMap
+ ,MyStdMultiMap>()){
+ std::cout << "Error in map_test<MyShmMap>" << std::endl;
+ return 1;
+ }
+
+// if (0 != map_test<my_managed_shared_memory
+// ,MyMovableShmMap
+// ,MyStdMap
+// ,MyMovableShmMultiMap
+// ,MyStdMultiMap>()){
+// return 1;
+// }
+
+ if (0 != map_test<my_managed_shared_memory
+ ,MyMoveCopyShmMap
+ ,MyStdMap
+ ,MyMoveCopyShmMultiMap
+ ,MyStdMultiMap>()){
+ std::cout << "Error in map_test<MyMoveCopyShmMap>" << std::endl;
+ return 1;
+ }
+
+ //#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);
+
+ if(!boost::interprocess::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<flat_multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<flat_set<test::EmplaceInt>, SetOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
+ return 1;
+ //#endif //!defined(__GNUC__)
+ return 0;
+
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/get_process_id_name.hpp b/src/boost/libs/interprocess/test/get_process_id_name.hpp
new file mode 100644
index 000000000..f79384ab8
--- /dev/null
+++ b/src/boost/libs/interprocess/test/get_process_id_name.hpp
@@ -0,0 +1,71 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_GET_PROCESS_ID_NAME_HPP
+#define BOOST_INTERPROCESS_GET_PROCESS_ID_NAME_HPP
+
+#include <boost/config.hpp>
+#include <string> //std::string
+#include <sstream> //std::stringstream
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+inline void get_process_id_name(std::string &str)
+{
+ std::stringstream sstr;
+ sstr << "process_" << boost::interprocess::ipcdetail::get_current_process_id() << std::ends;
+ str = sstr.str().c_str();
+}
+
+inline void get_process_id_ptr_name(std::string &str, const void *ptr)
+{
+ std::stringstream sstr;
+ sstr << "process_" << boost::interprocess::ipcdetail::get_current_process_id() << "_" << ptr << std::ends;
+ str = sstr.str().c_str();
+}
+
+inline const char *get_process_id_name()
+{
+ static std::string str;
+ get_process_id_name(str);
+ return str.c_str();
+}
+
+inline const char *get_process_id_ptr_name(void *ptr)
+{
+ static std::string str;
+ get_process_id_ptr_name(str, ptr);
+ return str.c_str();
+}
+
+inline const char *add_to_process_id_name(const char *name)
+{
+ static std::string str;
+ get_process_id_name(str);
+ str += name;
+ return str.c_str();
+}
+
+inline const char *add_to_process_id_ptr_name(const char *name, void *ptr)
+{
+ static std::string str;
+ get_process_id_ptr_name(str, ptr);
+ str += name;
+ return str.c_str();
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#endif //#ifndef BOOST_INTERPROCESS_GET_PROCESS_ID_NAME_HPP
diff --git a/src/boost/libs/interprocess/test/heap_allocator_v1.hpp b/src/boost/libs/interprocess/test/heap_allocator_v1.hpp
new file mode 100644
index 000000000..278d52e03
--- /dev/null
+++ b/src/boost/libs/interprocess/test/heap_allocator_v1.hpp
@@ -0,0 +1,166 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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_HEAP_ALLOCATOR_V1_HPP
+#define BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP
+
+#if defined (_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/intrusive/pointer_traits.hpp>
+
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/containers/allocation_type.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/containers/version_type.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/move/adl_move_swap.hpp>
+
+//!\file
+//!Describes an heap_allocator_v1 that allocates portions of fixed size
+//!memory buffer (shared memory, mapped file...)
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+//!An STL compatible heap_allocator_v1 that uses a segment manager as
+//!memory source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/
+template<class T, class SegmentManager>
+class heap_allocator_v1
+{
+ private:
+ typedef heap_allocator_v1<T, SegmentManager> self_t;
+ typedef SegmentManager segment_manager;
+ typedef typename segment_manager::void_pointer aux_pointer_t;
+
+ typedef typename boost::intrusive::
+ pointer_traits<aux_pointer_t>::template
+ rebind_pointer<const void>::type cvoid_ptr;
+
+ typedef typename boost::intrusive::
+ pointer_traits<cvoid_ptr>::template
+ rebind_pointer<segment_manager>::type alloc_ptr_t;
+
+ template<class T2, class SegmentManager2>
+ heap_allocator_v1& operator=(const heap_allocator_v1<T2, SegmentManager2>&);
+
+ heap_allocator_v1& operator=(const heap_allocator_v1&);
+
+ alloc_ptr_t mp_mngr;
+
+ public:
+ typedef T value_type;
+ typedef typename boost::intrusive::
+ pointer_traits<cvoid_ptr>::template
+ rebind_pointer<T>::type pointer;
+ typedef typename boost::intrusive::
+ pointer_traits<cvoid_ptr>::template
+ rebind_pointer<const T>::type const_pointer;
+ typedef typename ipcdetail::add_reference
+ <value_type>::type reference;
+ typedef typename ipcdetail::add_reference
+ <const value_type>::type const_reference;
+ typedef typename SegmentManager::size_type size_type;
+ typedef typename SegmentManager::difference_type difference_type;
+
+ //!Obtains an heap_allocator_v1 of other type
+ template<class T2>
+ struct rebind
+ {
+ typedef heap_allocator_v1<T2, SegmentManager> other;
+ };
+
+ //!Returns the segment manager. Never throws
+ segment_manager* get_segment_manager()const
+ { return ipcdetail::to_raw_pointer(mp_mngr); }
+
+ //!Returns address of mutable object. Never throws
+ pointer address(reference value) const
+ { return pointer(addressof(value)); }
+
+ //!Returns address of non mutable object. Never throws
+ const_pointer address(const_reference value) const
+ { return const_pointer(addressof(value)); }
+
+ //!Constructor from the segment manager. Never throws
+ heap_allocator_v1(segment_manager *segment_mngr)
+ : mp_mngr(segment_mngr) { }
+
+ //!Constructor from other heap_allocator_v1. Never throws
+ heap_allocator_v1(const heap_allocator_v1 &other)
+ : mp_mngr(other.get_segment_manager()){ }
+
+ //!Constructor from related heap_allocator_v1. Never throws
+ template<class T2>
+ heap_allocator_v1(const heap_allocator_v1<T2, SegmentManager> &other)
+ : mp_mngr(other.get_segment_manager()){}
+
+ //!Allocates memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate(size_type count, cvoid_ptr hint = 0)
+ {
+ (void)hint;
+ char *raw_mem = ::new char[sizeof(value_type)*count];
+ return boost::intrusive::pointer_traits<pointer>::pointer_to(reinterpret_cast<value_type &>(*raw_mem));
+ }
+
+ //!Deallocates memory previously allocated. Never throws
+ void deallocate(const pointer &ptr, size_type)
+ {
+ char *ptr_raw = (char*)ipcdetail::to_raw_pointer(ptr);
+ ::delete[] ptr_raw;
+ }
+
+ //!Construct object, calling constructor.
+ //!Throws if T(const T&) throws
+ void construct(const pointer &ptr, const_reference value)
+ { new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(value); }
+
+ //!Destroys object. Throws if object's destructor throws
+ void destroy(const pointer &ptr)
+ { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
+
+ //!Returns the number of elements that could be allocated. Never throws
+ size_type max_size() const
+ { return mp_mngr->get_size(); }
+
+ //!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
+ //!different memory segments, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2)
+ { ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
+};
+
+//!Equality test for same type of heap_allocator_v1
+template<class T, class SegmentManager> inline
+bool operator==(const heap_allocator_v1<T , SegmentManager> &alloc1,
+ const heap_allocator_v1<T, SegmentManager> &alloc2)
+ { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
+
+//!Inequality test for same type of heap_allocator_v1
+template<class T, class SegmentManager> inline
+bool operator!=(const heap_allocator_v1<T, SegmentManager> &alloc1,
+ const heap_allocator_v1<T, SegmentManager> &alloc2)
+ { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP
+
diff --git a/src/boost/libs/interprocess/test/intermodule_singleton_test.cpp b/src/boost/libs/interprocess/test/intermodule_singleton_test.cpp
new file mode 100644
index 000000000..915a9fe81
--- /dev/null
+++ b/src/boost/libs/interprocess/test/intermodule_singleton_test.cpp
@@ -0,0 +1,330 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/portable_intermodule_singleton.hpp>
+#include <iostream>
+#include <cstdlib> //for std::abort
+
+using namespace boost::interprocess;
+
+class MyClass
+{
+ public:
+ MyClass()
+ {
+ std::cout << "MyClass()\n" << std::endl;
+ }
+
+ void shout() const
+ {
+ std::cout << "Shout\n" << std::endl;
+ }
+
+ ~MyClass()
+ {
+ std::cout << "~MyClass()\n" << std::endl;
+ }
+};
+
+class MyDerivedClass
+ : public MyClass
+{};
+
+class MyThrowingClass
+{
+ public:
+ MyThrowingClass()
+ {
+ throw int(0);
+ }
+};
+
+
+template < template<class T, bool LazyInit, bool Phoenix> class IntermoduleType >
+int intermodule_singleton_test()
+{
+ bool exception_thrown = false;
+ bool exception_2_thrown = false;
+
+ try{
+ IntermoduleType<MyThrowingClass, true, false>::get();
+ }
+ catch(int &){
+ exception_thrown = true;
+ //Second try
+ try{
+ IntermoduleType<MyThrowingClass, true, false>::get();
+ }
+ catch(interprocess_exception &){
+ exception_2_thrown = true;
+ }
+ }
+
+ if(!exception_thrown || !exception_2_thrown){
+ return 1;
+ }
+
+ MyClass & mc = IntermoduleType<MyClass, true, false>::get();
+ mc.shout();
+ IntermoduleType<MyClass, true, false>::get().shout();
+ IntermoduleType<MyDerivedClass, true, false>::get().shout();
+
+ //Second try
+ exception_2_thrown = false;
+ try{
+ IntermoduleType<MyThrowingClass, true, false>::get();
+ }
+ catch(interprocess_exception &){
+ exception_2_thrown = true;
+ }
+ if(!exception_2_thrown){
+ return 1;
+ }
+
+ return 0;
+}
+
+//A class simulating a logger
+//We'll register constructor/destructor counts
+//to test the singleton was correctly resurrected
+//by LogUser singleton.
+template<class Tag>
+class Logger
+{
+ public:
+ Logger()
+ {
+ ++constructed_times;
+ std::cout << "Logger(),tag:" << typeid(Tag).name() << "(construct #" << constructed_times << ")\n" << std::endl;
+ }
+
+ void log_it()
+ {}
+
+ ~Logger()
+ {
+ ++destroyed_times;
+ std::cout << "~Logger(),tag:" << typeid(Tag).name() << "(destroy #" << destroyed_times << ")\n" << std::endl;
+ }
+
+ static unsigned int constructed_times;
+ static unsigned int destroyed_times;
+};
+
+template<class Tag>
+unsigned int Logger<Tag>::constructed_times;
+
+template<class Tag>
+unsigned int Logger<Tag>::destroyed_times;
+
+//A class simulating a logger user.
+//The destructor uses the logger so that
+//the logger is resurrected if it was
+//already destroyed
+template<class LogSingleton>
+class LogUser
+{
+ public:
+ LogUser()
+ {
+ std::cout << "LogUser(),tag:" << typeid(LogSingleton).name() << "\n" << std::endl;
+ }
+
+ void function_using_log()
+ { LogSingleton::get().log_it(); }
+
+ ~LogUser()
+ {
+ std::cout << "~LogUser(),tag:" << typeid(LogSingleton).name() << "\n" << std::endl;
+ LogSingleton::get().log_it();
+ }
+};
+
+//A class that tests the correct
+//phoenix singleton behaviour.
+//Logger should be resurrected by LogUser
+template<class Tag>
+class LogPhoenixTester
+{
+ public:
+ LogPhoenixTester()
+ {
+ std::cout << "LogPhoenixTester(), tag: " << typeid(Tag).name() << "\n" << std::endl;
+ }
+
+ void dummy()
+ {}
+
+ ~LogPhoenixTester()
+ {
+ //Test Phoenix singleton was correctly executed:
+ //created and destroyed two times
+ //This test will be executed after main ends
+ std::cout << "~LogPhoenixTester(), tag: " << typeid(Tag).name() << "\n" << std::endl;
+ if(Logger<Tag>::constructed_times != Logger<Tag>::destroyed_times ||
+ Logger<Tag>::constructed_times != 2)
+ {
+ std::stringstream sstr;
+ sstr << "LogPhoenixTester failed for tag ";
+ sstr << typeid(Tag).name();
+ sstr << "\n";
+ if(Logger<Tag>::constructed_times != 2){
+ sstr << "Logger<Tag>::constructed_times != 2\n";
+ sstr << "(";
+ sstr << Logger<Tag>::constructed_times << ")\n";
+ }
+ else{
+ sstr << "Logger<Tag>::constructed_times != Logger<Tag>::destroyed_times\n";
+ sstr << "(" << Logger<Tag>::constructed_times << " vs. " << Logger<Tag>::destroyed_times << ")\n";
+ }
+ std::cout << "~LogPhoenixTester(), error: " << sstr.str() << std::endl;
+ std::abort();
+ }
+ }
+};
+
+//A class simulating a logger user.
+//The destructor uses the logger so that
+//the logger is resurrected if it was
+//already destroyed
+template<class LogSingleton>
+class LogDeadReferenceUser
+{
+ public:
+ LogDeadReferenceUser()
+ {
+ std::cout << "LogDeadReferenceUser(), LogSingleton: " << typeid(LogSingleton).name() << "\n" << std::endl;
+ }
+
+ void function_using_log()
+ { LogSingleton::get().log_it(); }
+
+ ~LogDeadReferenceUser()
+ {
+ std::cout << "~LogDeadReferenceUser(), LogSingleton: " << typeid(LogSingleton).name() << "\n" << std::endl;
+ //Make sure the exception is thrown as we are
+ //trying to use a dead non-phoenix singleton
+ try{
+ LogSingleton::get().log_it();
+ std::string s("LogDeadReferenceUser failed for LogSingleton ");
+ s += typeid(LogSingleton).name();
+ std::cout << "~LogDeadReferenceUser(), error: " << s << std::endl;
+ std::abort();
+ }
+ catch(interprocess_exception &){
+ //Correct behaviour
+ }
+ }
+};
+
+template < template<class T, bool LazyInit, bool Phoenix> class IntermoduleType >
+int phoenix_singleton_test()
+{
+ typedef int DummyType;
+ typedef IntermoduleType<DummyType, true, true> Tag;
+ typedef Logger<Tag> LoggerType;
+ typedef IntermoduleType<LoggerType, true, true> LoggerSingleton;
+ typedef LogUser<LoggerSingleton> LogUserType;
+ typedef IntermoduleType<LogUserType, true, true> LogUserSingleton;
+ typedef IntermoduleType<LogPhoenixTester<Tag>, true, true> LogPhoenixTesterSingleton;
+
+ //Instantiate Phoenix tester singleton so that it will be destroyed the last
+ LogPhoenixTesterSingleton::get().dummy();
+
+ //Now instantitate a log user singleton
+ LogUserType &log_user = LogUserSingleton::get();
+
+ //Then force LoggerSingleton instantiation
+ //calling a function that will use it.
+ //After main ends, LoggerSingleton will be destroyed
+ //before LogUserSingleton due to LIFO
+ //singleton semantics
+ log_user.function_using_log();
+
+ //Next, LogUserSingleton destructor will resurrect
+ //LoggerSingleton.
+ //After that LoggerSingleton will be destroyed and
+ //lastly LogPhoenixTester will be destroyed checking
+ //LoggerSingleton was correctly destroyed.
+ return 0;
+}
+
+template < template<class T, bool LazyInit, bool Phoenix> class IntermoduleType >
+int dead_reference_singleton_test()
+{
+ typedef int DummyType;
+ typedef IntermoduleType<DummyType, true, false> Tag;
+ typedef Logger<Tag> LoggerType;
+ typedef IntermoduleType<LoggerType, true, false> LoggerSingleton;
+ typedef LogDeadReferenceUser<LoggerSingleton> LogDeadReferenceUserType;
+ typedef IntermoduleType<LogDeadReferenceUserType, true, false> LogDeadReferenceUserSingleton;
+
+ //Now instantitate a log user singleton
+ LogDeadReferenceUserType &log_user = LogDeadReferenceUserSingleton::get();
+
+ //Then force LoggerSingleton instantiation
+ //calling a function that will use it.
+ //After main ends, LoggerSingleton will be destroyed
+ //before LogDeadReferenceUserType due to LIFO
+ //singleton semantics
+ log_user.function_using_log();
+
+ //Next, LogDeadReferenceUserType destructor will try to use
+ //LoggerSingleton and an exception will be raised an catched.
+ return 0;
+}
+
+//reduce name length
+template<typename C, bool LazyInit, bool Phoenix>
+class port_singleton
+ : public ipcdetail::portable_intermodule_singleton<C, LazyInit, Phoenix>
+{};
+
+#ifdef BOOST_INTERPROCESS_WINDOWS
+template<typename C, bool LazyInit, bool Phoenix>
+class win_singleton
+ : public ipcdetail::windows_intermodule_singleton< C, LazyInit, Phoenix>
+{};
+#endif
+
+int main ()
+{
+ if(0 != intermodule_singleton_test<port_singleton>()){
+ return 1;
+ }
+
+ #ifdef BOOST_INTERPROCESS_WINDOWS
+ if(0 != intermodule_singleton_test<win_singleton>()){
+ return 1;
+ }
+ #endif
+
+ //Only few platforms support this
+ #ifdef BOOST_INTERPROCESS_ATEXIT_CALLABLE_FROM_ATEXIT
+ //Phoenix singletons are tested after main ends,
+ //LogPhoenixTester does the work
+ phoenix_singleton_test<port_singleton>();
+ #ifdef BOOST_INTERPROCESS_WINDOWS
+ phoenix_singleton_test<win_singleton>();
+ #endif
+ #endif
+
+ //Dead reference singletons are tested after main ends,
+ //LogDeadReferenceUser does the work
+ dead_reference_singleton_test<port_singleton>();
+ #ifdef BOOST_INTERPROCESS_WINDOWS
+ dead_reference_singleton_test<win_singleton>();
+ #endif
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/intrusive_ptr_test.cpp b/src/boost/libs/interprocess/test/intrusive_ptr_test.cpp
new file mode 100644
index 000000000..f3e481251
--- /dev/null
+++ b/src/boost/libs/interprocess/test/intrusive_ptr_test.cpp
@@ -0,0 +1,546 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Peter Dimov 2002-2005.
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/offset_ptr.hpp>
+#include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/config.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/core.hpp>
+#include <functional>
+
+typedef boost::interprocess::offset_ptr<void> VP;
+
+namespace {
+ int addref_release_calls = 0;
+}
+
+namespace N
+{
+
+class base
+{
+ private:
+
+ int use_count_;
+
+ base(base const &);
+ base & operator=(base const &);
+
+ protected:
+
+ base(): use_count_(0)
+ {
+ }
+
+ virtual ~base()
+ {
+ }
+
+ public:
+
+ long use_count() const
+ {
+ return use_count_;
+ }
+
+ void add_ref()
+ {
+ ++addref_release_calls;
+ ++use_count_;
+ }
+
+ void release()
+ {
+ ++addref_release_calls;
+ if(--use_count_ == 0) delete this;
+ }
+};
+
+inline void intrusive_ptr_add_ref(N::base *p)
+{ p->add_ref(); }
+
+inline void intrusive_ptr_release(N::base *p)
+{ p->release(); }
+
+} // namespace N
+
+struct X: public virtual N::base
+{
+};
+
+struct Y: public X
+{
+};
+
+//
+
+namespace n_element_type
+{
+
+void f(X &)
+{
+}
+
+void test()
+{
+ typedef boost::interprocess::intrusive_ptr<X, VP>::element_type T;
+ T t;
+ f(t);
+}
+
+} // namespace n_element_type
+
+namespace n_constructors
+{
+
+void default_constructor()
+{
+ boost::interprocess::intrusive_ptr<X, VP> px;
+ BOOST_TEST(px.get() == 0);
+}
+
+void pointer_constructor()
+{
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(0);
+ BOOST_TEST(px.get() == 0);
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(0, false);
+ BOOST_TEST(px.get() == 0);
+ }
+
+ {
+ boost::interprocess::offset_ptr<X> p = new X;
+ BOOST_TEST(p->use_count() == 0);
+
+ boost::interprocess::intrusive_ptr<X, VP> px(p);
+ BOOST_TEST(px.get() == p);
+ BOOST_TEST(px->use_count() == 1);
+ }
+
+ {
+ boost::interprocess::offset_ptr<X> p = new X;
+ BOOST_TEST(p->use_count() == 0);
+
+ intrusive_ptr_add_ref(p.get());
+ BOOST_TEST(p->use_count() == 1);
+
+ boost::interprocess::intrusive_ptr<X, VP> px(p, false);
+ BOOST_TEST(px.get() == p);
+ BOOST_TEST(px->use_count() == 1);
+ }
+}
+
+void copy_constructor()
+{
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px;
+ boost::interprocess::intrusive_ptr<X, VP> px2(px);
+ BOOST_TEST(px2.get() == px.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<Y, VP> py;
+ boost::interprocess::intrusive_ptr<X, VP> px(py);
+ BOOST_TEST(px.get() == py.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(0);
+ boost::interprocess::intrusive_ptr<X, VP> px2(px);
+ BOOST_TEST(px2.get() == px.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<Y, VP> py(0);
+ boost::interprocess::intrusive_ptr<X, VP> px(py);
+ BOOST_TEST(px.get() == py.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(0, false);
+ boost::interprocess::intrusive_ptr<X, VP> px2(px);
+ BOOST_TEST(px2.get() == px.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<Y, VP> py(0, false);
+ boost::interprocess::intrusive_ptr<X, VP> px(py);
+ BOOST_TEST(px.get() == py.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(new X);
+ boost::interprocess::intrusive_ptr<X, VP> px2(px);
+ BOOST_TEST(px2.get() == px.get());
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<Y, VP> py(new Y);
+ boost::interprocess::intrusive_ptr<X, VP> px(py);
+ BOOST_TEST(px.get() == py.get());
+ }
+}
+
+void move_constructor()
+{
+ {
+ int prev_addref_release_calls = addref_release_calls;
+ X* x = new X();
+ boost::interprocess::intrusive_ptr<X, VP> px(x);
+ BOOST_TEST(addref_release_calls == prev_addref_release_calls + 1);
+
+ //static_assert(std::is_nothrow_move_constructible< boost::interprocess::intrusive_ptr<X, VP> >::value, "test instrusive_ptr is nothrow move constructible");
+
+ boost::interprocess::intrusive_ptr<X, VP> px2(boost::move(px));
+ BOOST_TEST(px2.get() == x);
+ BOOST_TEST(!px.get());
+ BOOST_TEST(px2->use_count() == 1);
+ BOOST_TEST(addref_release_calls == prev_addref_release_calls + 1);
+ }
+}
+
+void test()
+{
+ default_constructor();
+ pointer_constructor();
+ copy_constructor();
+ move_constructor();
+}
+
+} // namespace n_constructors
+
+namespace n_destructor
+{
+
+void test()
+{
+ boost::interprocess::intrusive_ptr<X, VP> px(new X);
+ BOOST_TEST(px->use_count() == 1);
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px2(px);
+ BOOST_TEST(px->use_count() == 2);
+ }
+
+ BOOST_TEST(px->use_count() == 1);
+}
+
+} // namespace n_destructor
+
+namespace n_assignment
+{
+
+void copy_assignment()
+{
+}
+
+void move_assignment()
+{
+ {
+ int prev_addref_release_calls = addref_release_calls;
+ X* x = new X();
+ boost::interprocess::intrusive_ptr<X, VP> px(x);
+ BOOST_TEST(px->use_count() == 1);
+ BOOST_TEST(addref_release_calls == prev_addref_release_calls + 1);
+
+ //static_assert(std::is_nothrow_move_assignable< boost::interprocess::intrusive_ptr<X, VP> >::value, "test if nothrow move assignable ");
+
+ boost::interprocess::intrusive_ptr<X, VP> px2;
+ px2 = boost::move(px);
+ BOOST_TEST(px2.get() == x);
+ BOOST_TEST(!px.get());
+ BOOST_TEST(px2->use_count() == 1);
+ BOOST_TEST(addref_release_calls == prev_addref_release_calls + 1);
+ }
+}
+
+void conversion_assignment()
+{
+}
+
+void pointer_assignment()
+{
+}
+
+void test()
+{
+ copy_assignment();
+ conversion_assignment();
+ pointer_assignment();
+ move_assignment();
+}
+
+} // namespace n_assignment
+
+namespace n_access
+{
+
+void test()
+{
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px;
+ BOOST_TEST(px? false: true);
+ BOOST_TEST(!px);
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(0);
+ BOOST_TEST(px? false: true);
+ BOOST_TEST(!px);
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px
+ (boost::interprocess::offset_ptr<X>(new X));
+ BOOST_TEST(px? true: false);
+ BOOST_TEST(!!px);
+ BOOST_TEST(&*px == boost::interprocess::ipcdetail::to_raw_pointer(px.get()));
+ BOOST_TEST(px.operator ->() == px.get());
+ }
+}
+
+} // namespace n_access
+
+namespace n_swap
+{
+
+void test()
+{
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px;
+ boost::interprocess::intrusive_ptr<X, VP> px2;
+
+ px.swap(px2);
+
+ BOOST_TEST(px.get() == 0);
+ BOOST_TEST(px2.get() == 0);
+
+ ::boost::adl_move_swap(px, px2);
+
+ BOOST_TEST(px.get() == 0);
+ BOOST_TEST(px2.get() == 0);
+ }
+
+ {
+ boost::interprocess::offset_ptr<X> p = new X;
+ boost::interprocess::intrusive_ptr<X, VP> px;
+ boost::interprocess::intrusive_ptr<X, VP> px2(p);
+ boost::interprocess::intrusive_ptr<X, VP> px3(px2);
+
+ px.swap(px2);
+
+ BOOST_TEST(px.get() == p);
+ BOOST_TEST(px->use_count() == 2);
+ BOOST_TEST(px2.get() == 0);
+ BOOST_TEST(px3.get() == p);
+ BOOST_TEST(px3->use_count() == 2);
+
+ ::boost::adl_move_swap(px, px2);
+
+ BOOST_TEST(px.get() == 0);
+ BOOST_TEST(px2.get() == p);
+ BOOST_TEST(px2->use_count() == 2);
+ BOOST_TEST(px3.get() == p);
+ BOOST_TEST(px3->use_count() == 2);
+ }
+
+ {
+ boost::interprocess::offset_ptr<X> p1 = new X;
+ boost::interprocess::offset_ptr<X> p2 = new X;
+ boost::interprocess::intrusive_ptr<X, VP> px(p1);
+ boost::interprocess::intrusive_ptr<X, VP> px2(p2);
+ boost::interprocess::intrusive_ptr<X, VP> px3(px2);
+
+ px.swap(px2);
+
+ BOOST_TEST(px.get() == p2);
+ BOOST_TEST(px->use_count() == 2);
+ BOOST_TEST(px2.get() == p1);
+ BOOST_TEST(px2->use_count() == 1);
+ BOOST_TEST(px3.get() == p2);
+ BOOST_TEST(px3->use_count() == 2);
+
+ ::boost::adl_move_swap(px, px2);
+
+ BOOST_TEST(px.get() == p1);
+ BOOST_TEST(px->use_count() == 1);
+ BOOST_TEST(px2.get() == p2);
+ BOOST_TEST(px2->use_count() == 2);
+ BOOST_TEST(px3.get() == p2);
+ BOOST_TEST(px3->use_count() == 2);
+ }
+}
+
+} // namespace n_swap
+
+namespace n_comparison
+{
+
+template<class T, class U, class VP>
+void test2(boost::interprocess::intrusive_ptr<T, VP> const & p,
+ boost::interprocess::intrusive_ptr<U, VP> const & q)
+{
+ BOOST_TEST((p == q) == (p.get() == q.get()));
+ BOOST_TEST((p != q) == (p.get() != q.get()));
+}
+
+template<class T, class VP>
+void test3(boost::interprocess::intrusive_ptr<T, VP> const & p,
+ boost::interprocess::intrusive_ptr<T, VP> const & q)
+{
+ BOOST_TEST((p == q) == (p.get() == q.get()));
+ BOOST_TEST((p.get() == q) == (p.get() == q.get()));
+ BOOST_TEST((p == q.get()) == (p.get() == q.get()));
+ BOOST_TEST((p != q) == (p.get() != q.get()));
+ BOOST_TEST((p.get() != q) == (p.get() != q.get()));
+ BOOST_TEST((p != q.get()) == (p.get() != q.get()));
+
+ // 'less' moved here as a g++ 2.9x parse error workaround
+ std::less<boost::interprocess::offset_ptr<T> > less;
+ BOOST_TEST((p < q) == less(p.get(), q.get()));
+}
+
+void test()
+{
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px;
+ test3(px, px);
+
+ boost::interprocess::intrusive_ptr<X, VP> px2;
+ test3(px, px2);
+
+ boost::interprocess::intrusive_ptr<X, VP> px3(px);
+ test3(px3, px3);
+ test3(px, px3);
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px;
+
+ boost::interprocess::intrusive_ptr<X, VP> px2(new X);
+ test3(px, px2);
+ test3(px2, px2);
+
+ boost::interprocess::intrusive_ptr<X, VP> px3(new X);
+ test3(px2, px3);
+
+ boost::interprocess::intrusive_ptr<X, VP> px4(px2);
+ test3(px2, px4);
+ test3(px4, px4);
+ }
+
+ {
+ boost::interprocess::intrusive_ptr<X, VP> px(new X);
+
+ boost::interprocess::intrusive_ptr<Y, VP> py(new Y);
+ test2(px, py);
+
+ boost::interprocess::intrusive_ptr<X, VP> px2(py);
+ test2(px2, py);
+ test3(px, px2);
+ test3(px2, px2);
+ }
+}
+
+} // namespace n_comparison
+
+namespace n_static_cast
+{
+
+void test()
+{
+}
+
+} // namespace n_static_cast
+
+namespace n_dynamic_cast
+{
+
+void test()
+{
+}
+
+} // namespace n_dynamic_cast
+
+namespace n_transitive
+{
+
+struct X: public N::base
+{
+ boost::interprocess::intrusive_ptr<X, VP> next;
+};
+
+void test()
+{
+ boost::interprocess::intrusive_ptr<X, VP> p(new X);
+ p->next = boost::interprocess::intrusive_ptr<X, VP>(new X);
+ BOOST_TEST(!p->next->next);
+ p = p->next;
+ BOOST_TEST(!p->next);
+}
+
+} // namespace n_transitive
+
+namespace n_report_1
+{
+
+class foo: public N::base
+{
+ public:
+
+ foo(): m_self(this)
+ {
+ }
+
+ void suicide()
+ {
+ m_self = 0;
+ }
+
+ private:
+
+ boost::interprocess::intrusive_ptr<foo, VP> m_self;
+};
+
+void test()
+{
+ boost::interprocess::offset_ptr<foo> foo_ptr = new foo;
+ foo_ptr->suicide();
+}
+
+} // namespace n_report_1
+
+int main()
+{
+ n_element_type::test();
+ n_constructors::test();
+ n_destructor::test();
+ n_assignment::test();
+ n_access::test();
+ n_swap::test();
+ n_comparison::test();
+ n_static_cast::test();
+ n_dynamic_cast::test();
+
+ n_transitive::test();
+ n_report_1::test();
+
+ return boost::report_errors();
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/iset_index_allocation_test.cpp b/src/boost/libs/interprocess/test/iset_index_allocation_test.cpp
new file mode 100644
index 000000000..42d03ff8d
--- /dev/null
+++ b/src/boost/libs/interprocess/test/iset_index_allocation_test.cpp
@@ -0,0 +1,24 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/indexes/iset_index.hpp>
+#include "named_allocation_test_template.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+ if(!test::test_named_allocation<iset_index>()){
+ return 1;
+ }
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/iunordered_set_index_allocation_test.cpp b/src/boost/libs/interprocess/test/iunordered_set_index_allocation_test.cpp
new file mode 100644
index 000000000..5e8e966d5
--- /dev/null
+++ b/src/boost/libs/interprocess/test/iunordered_set_index_allocation_test.cpp
@@ -0,0 +1,25 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/indexes/iunordered_set_index.hpp>
+#include "named_allocation_test_template.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+ if(!test::test_named_allocation<iunordered_set_index>()){
+ return 1;
+ }
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/list_test.cpp b/src/boost/libs/interprocess/test/list_test.cpp
new file mode 100644
index 000000000..4ecf55a48
--- /dev/null
+++ b/src/boost/libs/interprocess/test/list_test.cpp
@@ -0,0 +1,63 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/offset_ptr.hpp>
+#include "dummy_test_allocator.hpp"
+#include "list_test.hpp"
+#include "movable_int.hpp"
+#include "emplace_test.hpp"
+
+using namespace boost::interprocess;
+
+typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
+typedef list<int, ShmemAllocator> MyList;
+
+//typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
+//typedef list<volatile int, ShmemVolatileAllocator> MyVolatileList;
+
+typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
+typedef list<test::movable_int, ShmemMoveAllocator> MyMoveList;
+
+typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
+typedef list<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveList;
+
+typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator;
+typedef list<test::copyable_int, ShmemCopyAllocator> MyCopyList;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyList, true>())
+ return 1;
+
+// if(test::list_test<managed_shared_memory, MyVolatileList, true>())
+// return 1;
+
+ if(test::list_test<managed_shared_memory, MyMoveList, true>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyCopyMoveList, true>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyCopyList, true>())
+ return 1;
+
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
+
+ if(!boost::interprocess::test::test_emplace<list<test::EmplaceInt>, Options>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/list_test.hpp b/src/boost/libs/interprocess/test/list_test.hpp
new file mode 100644
index 000000000..a7c406334
--- /dev/null
+++ b/src/boost/libs/interprocess/test/list_test.hpp
@@ -0,0 +1,281 @@
+////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_TEST_LIST_TEST_HEADER
+#define BOOST_INTERPROCESS_TEST_LIST_TEST_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include "check_equal_containers.hpp"
+#include <memory>
+#include <list>
+#include <vector>
+#include <functional>
+#include "print_container.hpp"
+#include <boost/move/utility_core.hpp>
+#include <string>
+#include "get_process_id_name.hpp"
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template<bool DoublyLinked>
+struct push_data_function
+{
+ template<class MyShmList, class MyStdList>
+ static int execute(int max, MyShmList *shmlist, MyStdList *stdlist)
+ {
+ typedef typename MyShmList::value_type IntType;
+ for(int i = 0; i < max; ++i){
+ IntType move_me(i);
+ shmlist->push_back(boost::move(move_me));
+ stdlist->push_back(i);
+ shmlist->push_back(IntType(i));
+ stdlist->push_back(int(i));
+ }
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ return 0;
+ }
+};
+
+template<>
+struct push_data_function<false>
+{
+ template<class MyShmList, class MyStdList>
+ static int execute(int max, MyShmList *shmlist, MyStdList *stdlist)
+ {
+ typedef typename MyShmList::value_type IntType;
+ for(int i = 0; i < max; ++i){
+ IntType move_me(i);
+ shmlist->push_front(boost::move(move_me));
+ stdlist->push_front(i);
+ shmlist->push_front(IntType(i));
+ stdlist->push_front(int(i));
+ }
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ return 0;
+ }
+};
+
+template<bool DoublyLinked>
+struct pop_back_function
+{
+ template<class MyStdList, class MyShmList>
+ static int execute(MyShmList *shmlist, MyStdList *stdlist)
+ {
+ shmlist->pop_back();
+ stdlist->pop_back();
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ return 0;
+ }
+};
+
+template<>
+struct pop_back_function<false>
+{
+ template<class MyStdList, class MyShmList>
+ static int execute(MyShmList *shmlist, MyStdList *stdlist)
+ {
+ (void)shmlist; (void)stdlist;
+ return 0;
+ }
+};
+
+template<class ManagedSharedMemory
+ ,class MyShmList
+ ,bool DoublyLinked>
+int list_test (bool copied_allocators_equal = true)
+{
+ typedef std::list<int> MyStdList;
+ typedef typename MyShmList::value_type IntType;
+ const int memsize = 65536;
+ const char *const shMemName = test::get_process_id_name();
+ const int max = 100;
+ typedef push_data_function<DoublyLinked> push_data_t;
+
+ try{
+ //Named new capable shared mem allocator
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ ManagedSharedMemory segment(create_only, shMemName, memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmList *shmlist = segment.template construct<MyShmList>("MyList")
+ (segment.get_segment_manager());
+
+
+ MyStdList *stdlist = new MyStdList;
+
+ if(push_data_t::execute(max/2, shmlist, stdlist)){
+ return 1;
+ }
+
+ shmlist->erase(shmlist->begin()++);
+ stdlist->erase(stdlist->begin()++);
+ if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+
+ if(pop_back_function<DoublyLinked>::execute(shmlist, stdlist)){
+ return 1;
+ }
+
+ shmlist->pop_front();
+ stdlist->pop_front();
+ if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ shmlist->assign(::boost::make_move_iterator(&aux_vect[0])
+ ,::boost::make_move_iterator(&aux_vect[50]));
+ stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
+ if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ }
+
+ if(copied_allocators_equal){
+ shmlist->sort();
+ stdlist->sort();
+ if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ }
+
+ shmlist->reverse();
+ stdlist->reverse();
+ if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+
+ shmlist->reverse();
+ stdlist->reverse();
+ if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ shmlist->insert(shmlist->begin()
+ ,::boost::make_move_iterator(&aux_vect[0])
+ ,::boost::make_move_iterator(&aux_vect[50]));
+ stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
+ }
+
+ shmlist->unique();
+ stdlist->unique();
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+
+ if(copied_allocators_equal){
+ shmlist->sort(std::greater<IntType>());
+ stdlist->sort(std::greater<int>());
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ }
+
+ shmlist->resize(25);
+ stdlist->resize(25);
+ shmlist->resize(50);
+ stdlist->resize(50);
+ shmlist->resize(0);
+ stdlist->resize(0);
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+
+ if(push_data_t::execute(max/2, shmlist, stdlist)){
+ return 1;
+ }
+ {
+ MyShmList othershmlist(shmlist->get_allocator());
+ MyStdList otherstdlist;
+
+ int listsize = (int)shmlist->size();
+
+ if(push_data_t::execute(listsize/2, shmlist, stdlist)){
+ return 1;
+ }
+
+ if(copied_allocators_equal){
+ shmlist->splice(shmlist->begin(), othershmlist);
+ stdlist->splice(stdlist->begin(), otherstdlist);
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ }
+
+ listsize = (int)shmlist->size();
+
+ if(push_data_t::execute(listsize/2, shmlist, stdlist)){
+ return 1;
+ }
+
+ if(push_data_t::execute(listsize/2, &othershmlist, &otherstdlist)){
+ return 1;
+ }
+
+ if(copied_allocators_equal){
+ shmlist->sort(std::greater<IntType>());
+ stdlist->sort(std::greater<int>());
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+
+ othershmlist.sort(std::greater<IntType>());
+ otherstdlist.sort(std::greater<int>());
+ if(!CheckEqualContainers(&othershmlist, &otherstdlist))
+ return 1;
+
+ shmlist->merge(othershmlist, std::greater<IntType>());
+ stdlist->merge(otherstdlist, std::greater<int>());
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ }
+
+ for(int i = 0; i < max; ++i){
+ shmlist->insert(shmlist->begin(), IntType(i));
+ stdlist->insert(stdlist->begin(), int(i));
+ }
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
+ }
+
+ segment.template destroy<MyShmList>("MyList");
+ delete stdlist;
+ segment.shrink_to_fit_indexes();
+
+ if(!segment.all_memory_deallocated())
+ return 1;
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif
diff --git a/src/boost/libs/interprocess/test/managed_mapped_file_test.cpp b/src/boost/libs/interprocess/test/managed_mapped_file_test.cpp
new file mode 100644
index 000000000..8185e56c1
--- /dev/null
+++ b/src/boost/libs/interprocess/test/managed_mapped_file_test.cpp
@@ -0,0 +1,239 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+
+#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
+
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/managed_mapped_file.hpp>
+#include <cstdio>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+inline std::string get_filename()
+{
+ std::string ret (ipcdetail::get_temporary_path());
+ ret += "/";
+ ret += test::get_process_id_name();
+ return ret;
+}
+
+int main ()
+{
+ const int FileSize = 65536*10;
+ std::string filename(get_filename());
+ const char *FileName = filename.c_str();
+
+ //STL compatible allocator object for memory-mapped file
+ typedef allocator<int, managed_mapped_file::segment_manager>
+ allocator_int_t;
+ //A vector that uses that allocator
+ typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
+
+ {
+ //Remove the file it is already created
+ file_mapping::remove(FileName);
+
+ const int max = 100;
+ void *array[max];
+ //Named allocate capable shared memory allocator
+ managed_mapped_file mfile(create_only, FileName, FileSize);
+
+ int i;
+ //Let's allocate some memory
+ for(i = 0; i < max; ++i){
+ array[i] = mfile.allocate(i+1);
+ }
+
+ //Deallocate allocated memory
+ for(i = 0; i < max; ++i){
+ mfile.deallocate(array[i]);
+ }
+ }
+
+ {
+ //Remove the file it is already created
+ file_mapping::remove(FileName);
+
+ //Named allocate capable memory mapped file managed memory class
+ managed_mapped_file mfile(create_only, FileName, FileSize);
+
+ //Construct the STL-like allocator with the segment manager
+ const allocator_int_t myallocator (mfile.get_segment_manager());
+
+ //Construct vector
+ MyVect *mfile_vect = mfile.construct<MyVect> ("MyVector") (myallocator);
+
+ //Test that vector can be found via name
+ if(mfile_vect != mfile.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Destroy and check it is not present
+ mfile.destroy<MyVect> ("MyVector");
+ if(0 != mfile.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Construct a vector in the memory-mapped file
+ mfile_vect = mfile.construct<MyVect> ("MyVector") (myallocator);
+
+ //Flush cached data from memory-mapped file to disk
+ mfile.flush();
+ }
+ {
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+
+ //Check vector is still there
+ MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(!mfile_vect)
+ return -1;
+ }
+
+ {
+ {
+ //Map preexisting file again in copy-on-write
+ managed_mapped_file mfile(open_copy_on_write, FileName);
+
+ //Check vector is still there
+ MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(!mfile_vect)
+ return -1;
+
+ //Erase vector
+ mfile.destroy_ptr(mfile_vect);
+
+ //Make sure vector is erased
+ mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(mfile_vect)
+ return -1;
+ }
+ //Now check vector is still in the file
+ {
+ //Map preexisting file again in copy-on-write
+ managed_mapped_file mfile(open_copy_on_write, FileName);
+
+ //Check vector is still there
+ MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(!mfile_vect)
+ return -1;
+ }
+ }
+ {
+ //Map preexisting file again in copy-on-write
+ managed_mapped_file mfile(open_read_only, FileName);
+
+ //Check vector is still there
+ MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(!mfile_vect)
+ return -1;
+ }
+ {
+ managed_mapped_file::size_type old_free_memory;
+ {
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+ old_free_memory = mfile.get_free_memory();
+ }
+
+ //Now grow the file
+ managed_mapped_file::grow(FileName, FileSize);
+
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+
+ //Check vector is still there
+ MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(!mfile_vect)
+ return -1;
+
+ if(mfile.get_size() != (FileSize*2))
+ return -1;
+ if(mfile.get_free_memory() <= old_free_memory)
+ return -1;
+ }
+ {
+ managed_mapped_file::size_type old_free_memory, next_free_memory,
+ old_file_size, next_file_size, final_file_size;
+ {
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+ old_free_memory = mfile.get_free_memory();
+ old_file_size = mfile.get_size();
+ }
+
+ //Now shrink the file
+ managed_mapped_file::shrink_to_fit(FileName);
+
+ {
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+ next_file_size = mfile.get_size();
+
+ //Check vector is still there
+ MyVect *mfile_vect = mfile.find<MyVect>("MyVector").first;
+ if(!mfile_vect)
+ return -1;
+
+ next_free_memory = mfile.get_free_memory();
+ if(next_free_memory >= old_free_memory)
+ return -1;
+ if(old_file_size <= next_file_size)
+ return -1;
+ }
+
+ //Now destroy the vector
+ {
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+
+ //Destroy and check it is not present
+ mfile.destroy<MyVect>("MyVector");
+ if(0 != mfile.find<MyVect>("MyVector").first)
+ return -1;
+ }
+
+ //Now shrink the file
+ managed_mapped_file::shrink_to_fit(FileName);
+ {
+ //Map preexisting file again in memory
+ managed_mapped_file mfile(open_only, FileName);
+ final_file_size = mfile.get_size();
+ if(next_file_size <= final_file_size)
+ return -1;
+ }
+ {
+ //Now test move semantics
+ managed_mapped_file original(open_only, FileName);
+ managed_mapped_file move_ctor(boost::move(original));
+ managed_mapped_file move_assign;
+ move_assign = boost::move(move_ctor);
+ move_assign.swap(original);
+ }
+ }
+
+ file_mapping::remove(FileName);
+ return 0;
+}
+
+#else //#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
+
+int main()
+{
+ return 0;
+}
+
+#endif//#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/managed_shared_memory_test.cpp b/src/boost/libs/interprocess/test/managed_shared_memory_test.cpp
new file mode 100644
index 000000000..df8508226
--- /dev/null
+++ b/src/boost/libs/interprocess/test/managed_shared_memory_test.cpp
@@ -0,0 +1,216 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/allocators/allocator.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <cstdio>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ const int ShmemSize = 65536;
+ const char *const ShmemName = test::get_process_id_name();
+
+ //STL compatible allocator object for memory-mapped shmem
+ typedef allocator<int, managed_shared_memory::segment_manager>
+ allocator_int_t;
+ //A vector that uses that allocator
+ typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
+
+ {
+ //Remove the shmem it is already created
+ shared_memory_object::remove(ShmemName);
+
+ const int max = 100;
+ void *array[max];
+ //Named allocate capable shared memory allocator
+ managed_shared_memory shmem(create_only, ShmemName, ShmemSize);
+
+ int i;
+ //Let's allocate some memory
+ for(i = 0; i < max; ++i){
+ array[i] = shmem.allocate(i+1);
+ }
+
+ //Deallocate allocated memory
+ for(i = 0; i < max; ++i){
+ shmem.deallocate(array[i]);
+ }
+ }
+
+ {
+ //Remove the shmem it is already created
+ shared_memory_object::remove(ShmemName);
+
+ //Named allocate capable memory mapped shmem managed memory class
+ managed_shared_memory shmem(create_only, ShmemName, ShmemSize);
+
+ //Construct the STL-like allocator with the segment manager
+ const allocator_int_t myallocator (shmem.get_segment_manager());
+
+ //Construct vector
+ MyVect *shmem_vect = shmem.construct<MyVect> ("MyVector") (myallocator);
+
+ //Test that vector can be found via name
+ if(shmem_vect != shmem.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Destroy and check it is not present
+ shmem.destroy<MyVect> ("MyVector");
+ if(0 != shmem.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Construct a vector in the memory-mapped shmem
+ shmem_vect = shmem.construct<MyVect> ("MyVector") (myallocator);
+ }
+ {
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+ }
+ {
+ {
+ //Map preexisting shmem again in copy-on-write
+ managed_shared_memory shmem(open_copy_on_write, ShmemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+
+ //Erase vector
+ shmem.destroy_ptr(shmem_vect);
+
+ //Make sure vector is erased
+ shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(shmem_vect)
+ return -1;
+ }
+ //Now check vector is still in the shmem
+ {
+ //Map preexisting shmem again in copy-on-write
+ managed_shared_memory shmem(open_copy_on_write, ShmemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+ }
+ }
+ {
+ //Map preexisting shmem again in copy-on-write
+ managed_shared_memory shmem(open_read_only, ShmemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+ }
+ #ifndef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
+ {
+ managed_shared_memory::size_type old_free_memory;
+ {
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+ old_free_memory = shmem.get_free_memory();
+ }
+
+ //Now grow the shmem
+ managed_shared_memory::grow(ShmemName, ShmemSize);
+
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+
+ if(shmem.get_size() != (ShmemSize*2))
+ return -1;
+ if(shmem.get_free_memory() <= old_free_memory)
+ return -1;
+ }
+ {
+ managed_shared_memory::size_type old_free_memory, next_free_memory,
+ old_shmem_size, next_shmem_size, final_shmem_size;
+ {
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+ old_free_memory = shmem.get_free_memory();
+ old_shmem_size = shmem.get_size();
+ }
+
+ //Now shrink the shmem
+ managed_shared_memory::shrink_to_fit(ShmemName);
+
+ {
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+ next_shmem_size = shmem.get_size();
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+
+ next_free_memory = shmem.get_free_memory();
+ if(next_free_memory >= old_free_memory)
+ return -1;
+ if(old_shmem_size <= next_shmem_size)
+ return -1;
+ }
+
+ //Now destroy the vector
+ {
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+
+ //Destroy and check it is not present
+ shmem.destroy<MyVect>("MyVector");
+ if(0 != shmem.find<MyVect>("MyVector").first)
+ return -1;
+ }
+
+ //Now shrink the shmem
+ managed_shared_memory::shrink_to_fit(ShmemName);
+ {
+ //Map preexisting shmem again in memory
+ managed_shared_memory shmem(open_only, ShmemName);
+ final_shmem_size = shmem.get_size();
+ if(next_shmem_size <= final_shmem_size)
+ return -1;
+ }
+ }
+ #endif //ifndef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
+
+ {
+ //Now test move semantics
+ managed_shared_memory original(open_only, ShmemName);
+ managed_shared_memory move_ctor(boost::move(original));
+ managed_shared_memory move_assign;
+ move_assign = boost::move(move_ctor);
+ move_assign.swap(original);
+ }
+
+ shared_memory_object::remove(ShmemName);
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/managed_windows_shared_memory_test.cpp b/src/boost/libs/interprocess/test/managed_windows_shared_memory_test.cpp
new file mode 100644
index 000000000..aa01119e4
--- /dev/null
+++ b/src/boost/libs/interprocess/test/managed_windows_shared_memory_test.cpp
@@ -0,0 +1,152 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_INTERPROCESS_WINDOWS
+
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/managed_windows_shared_memory.hpp>
+#include <cstdio>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ const int MemSize = 65536;
+ const char *const MemName = test::get_process_id_name();
+
+ //STL compatible allocator object for shared memory
+ typedef allocator<int, managed_windows_shared_memory::segment_manager>
+ allocator_int_t;
+ //A vector that uses that allocator
+ typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
+
+ {
+ const int max = 100;
+ void *array[max];
+ //Named allocate capable shared memory allocator
+ managed_windows_shared_memory w_shm(create_only, MemName, MemSize);
+
+ int i;
+ //Let's allocate some memory
+ for(i = 0; i < max; ++i){
+ array[i] = w_shm.allocate(i+1);
+ }
+
+ //Deallocate allocated memory
+ for(i = 0; i < max; ++i){
+ w_shm.deallocate(array[i]);
+ }
+ }
+
+ {
+ //Named allocate capable shared memory managed memory class
+ managed_windows_shared_memory w_shm(create_only, MemName, MemSize);
+
+ //Construct the STL-like allocator with the segment manager
+ const allocator_int_t myallocator (w_shm.get_segment_manager());
+
+ //Construct vector
+ MyVect *w_shm_vect = w_shm.construct<MyVect> ("MyVector") (myallocator);
+
+ //Test that vector can be found via name
+ if(w_shm_vect != w_shm.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Destroy and check it is not present
+ w_shm.destroy<MyVect> ("MyVector");
+ if(0 != w_shm.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Construct a vector in the shared memory
+ w_shm_vect = w_shm.construct<MyVect> ("MyVector") (myallocator);
+
+ {
+ //Map preexisting segment again in memory
+ managed_windows_shared_memory w_shm_new(open_only, MemName);
+
+ //Check vector is still there
+ w_shm_vect = w_shm_new.find<MyVect>("MyVector").first;
+ if(!w_shm_vect)
+ return -1;
+
+ if(w_shm_new.get_size() != w_shm.get_size())
+ return 1;
+
+ {
+ {
+ //Map preexisting shmem again in copy-on-write
+ managed_windows_shared_memory shmem(open_copy_on_write, MemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+
+ //Erase vector
+ shmem.destroy_ptr(shmem_vect);
+
+ //Make sure vector is erased
+ shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(shmem_vect)
+ return -1;
+ }
+ //Now check vector is still in the s
+ {
+ //Map preexisting shmem again in copy-on-write
+ managed_windows_shared_memory shmem(open_copy_on_write, MemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+ }
+ }
+ {
+ //Map preexisting shmem again in copy-on-write
+ managed_windows_shared_memory shmem(open_read_only, MemName);
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+ }
+
+ //Destroy and check it is not present
+ w_shm_new.destroy_ptr(w_shm_vect);
+ if(0 != w_shm_new.find<MyVect>("MyVector").first)
+ return 1;
+
+ //Now test move semantics
+ managed_windows_shared_memory original(open_only, MemName);
+ managed_windows_shared_memory move_ctor(boost::move(original));
+ managed_windows_shared_memory move_assign;
+ move_assign = boost::move(move_ctor);
+ }
+ }
+
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/managed_xsi_shared_memory_test.cpp b/src/boost/libs/interprocess/test/managed_xsi_shared_memory_test.cpp
new file mode 100644
index 000000000..149259649
--- /dev/null
+++ b/src/boost/libs/interprocess/test/managed_xsi_shared_memory_test.cpp
@@ -0,0 +1,174 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2012. 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>
+
+#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/managed_xsi_shared_memory.hpp>
+#include <boost/interprocess/detail/file_wrapper.hpp>
+#include <boost/interprocess/file_mapping.hpp>
+#include <cstdio>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+void remove_shared_memory(const xsi_key &key)
+{
+ try{
+ xsi_shared_memory xsi(open_only, key);
+ xsi_shared_memory::remove(xsi.get_shmid());
+ }
+ catch(interprocess_exception &e){
+ if(e.get_error_code() != not_found_error)
+ throw;
+ }
+}
+
+class xsi_shared_memory_remover
+{
+ public:
+ xsi_shared_memory_remover(xsi_shared_memory &xsi_shm)
+ : xsi_shm_(xsi_shm)
+ {}
+
+ ~xsi_shared_memory_remover()
+ { xsi_shared_memory::remove(xsi_shm_.get_shmid()); }
+ private:
+ xsi_shared_memory & xsi_shm_;
+};
+
+inline std::string get_filename()
+{
+ std::string ret (ipcdetail::get_temporary_path());
+ ret += "/";
+ ret += test::get_process_id_name();
+ return ret;
+}
+
+int main ()
+{
+ const int ShmemSize = 65536;
+ std::string filename = get_filename();
+ const char *const ShmemName = filename.c_str();
+
+ file_mapping::remove(ShmemName);
+ { ipcdetail::file_wrapper(create_only, ShmemName, read_write); }
+ xsi_key key(ShmemName, 1);
+ file_mapping::remove(ShmemName);
+ int shmid;
+
+ //STL compatible allocator object for memory-mapped shmem
+ typedef allocator<int, managed_xsi_shared_memory::segment_manager>
+ allocator_int_t;
+ //A vector that uses that allocator
+ typedef boost::interprocess::vector<int, allocator_int_t> MyVect;
+
+ {
+ //Remove the shmem it is already created
+ remove_shared_memory(key);
+
+ const int max = 100;
+ void *array[max];
+ //Named allocate capable shared memory allocator
+ managed_xsi_shared_memory shmem(create_only, key, ShmemSize);
+ shmid = shmem.get_shmid();
+ int i;
+ //Let's allocate some memory
+ for(i = 0; i < max; ++i){
+ array[i] = shmem.allocate(i+1);
+ }
+
+ //Deallocate allocated memory
+ for(i = 0; i < max; ++i){
+ shmem.deallocate(array[i]);
+ }
+ }
+
+ {
+ //Remove the shmem it is already created
+ xsi_shared_memory::remove(shmid);
+
+ //Named allocate capable memory mapped shmem managed memory class
+ managed_xsi_shared_memory shmem(create_only, key, ShmemSize);
+ shmid = shmem.get_shmid();
+
+ //Construct the STL-like allocator with the segment manager
+ const allocator_int_t myallocator (shmem.get_segment_manager());
+
+ //Construct vector
+ MyVect *shmem_vect = shmem.construct<MyVect> ("MyVector") (myallocator);
+
+ //Test that vector can be found via name
+ if(shmem_vect != shmem.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Destroy and check it is not present
+ shmem.destroy<MyVect> ("MyVector");
+ if(0 != shmem.find<MyVect>("MyVector").first)
+ return -1;
+
+ //Construct a vector in the memory-mapped shmem
+ shmem_vect = shmem.construct<MyVect> ("MyVector") (myallocator);
+ }
+ {
+ //Map preexisting shmem again in memory
+ managed_xsi_shared_memory shmem(open_only, key);
+ shmid = shmem.get_shmid();
+
+ //Check vector is still there
+ MyVect *shmem_vect = shmem.find<MyVect>("MyVector").first;
+ if(!shmem_vect)
+ return -1;
+ }
+
+
+ {
+ //Now destroy the vector
+ {
+ //Map preexisting shmem again in memory
+ managed_xsi_shared_memory shmem(open_only, key);
+ shmid = shmem.get_shmid();
+
+ //Destroy and check it is not present
+ shmem.destroy<MyVect>("MyVector");
+ if(0 != shmem.find<MyVect>("MyVector").first)
+ return -1;
+ }
+
+ {
+ //Now test move semantics
+ managed_xsi_shared_memory original(open_only, key);
+ managed_xsi_shared_memory move_ctor(boost::move(original));
+ managed_xsi_shared_memory move_assign;
+ move_assign = boost::move(move_ctor);
+ move_assign.swap(original);
+ }
+ }
+
+ xsi_shared_memory::remove(shmid);
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif //#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/map_index_allocation_test.cpp b/src/boost/libs/interprocess/test/map_index_allocation_test.cpp
new file mode 100644
index 000000000..27078f457
--- /dev/null
+++ b/src/boost/libs/interprocess/test/map_index_allocation_test.cpp
@@ -0,0 +1,25 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/indexes/map_index.hpp>
+#include "named_allocation_test_template.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+ if(!test::test_named_allocation<map_index>()){
+ return 1;
+ }
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/map_test.hpp b/src/boost/libs/interprocess/test/map_test.hpp
new file mode 100644
index 000000000..0a20a7876
--- /dev/null
+++ b/src/boost/libs/interprocess/test/map_test.hpp
@@ -0,0 +1,593 @@
+////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_TEST_MAP_TEST_HEADER
+#define BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include "check_equal_containers.hpp"
+#include <map>
+
+// interprocess
+#include <boost/interprocess/containers/pair.hpp>
+// interprocess/detail
+#include <boost/interprocess/detail/utilities.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>
+// std
+#include <string>
+
+#include "print_container.hpp"
+#include "get_process_id_name.hpp"
+
+template<class T1, class T2, class T3, class T4>
+bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
+{
+ return p1.first == p2.first && p1.second == p2.second;
+}
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template<class ManagedSharedMemory
+ ,class MyShmMap
+ ,class MyStdMap
+ ,class MyShmMultiMap
+ ,class MyStdMultiMap>
+int map_test ()
+{
+ typedef typename MyShmMap::key_type IntType;
+ 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();
+ const int max = 100;
+
+ try{
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ ManagedSharedMemory segment(create_only, shMemName, memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmMap *shmmap =
+ segment.template construct<MyShmMap>("MyShmMap")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMap *stdmap = new MyStdMap;
+
+ MyShmMultiMap *shmmultimap =
+ segment.template construct<MyShmMultiMap>("MyShmMultiMap")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiMap *stdmultimap = new MyStdMultiMap;
+
+ //Test construction from a range
+ {
+ //This is really nasty, but we have no other simple choice
+ IntPairType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(i/2);
+ IntType i2(i/2);
+ new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ typedef typename MyStdMap::value_type StdValueType;
+ typedef typename MyStdMap::key_type StdKeyType;
+ typedef typename MyStdMap::mapped_type StdMappedType;
+ StdValueType aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ new(&aux_vect2[i])StdValueType(StdKeyType(i/2), StdMappedType(i/2));
+ }
+
+ IntPairType aux_vect3[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(i/2);
+ IntType i2(i/2);
+ new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ MyShmMap *shmmap2 =
+ segment.template construct<MyShmMap>("MyShmMap2")
+ ( ::boost::make_move_iterator(&aux_vect[0])
+ , ::boost::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")
+ ( ::boost::make_move_iterator(&aux_vect3[0])
+ , ::boost::make_move_iterator(aux_vect3 + 50)
+ , std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiMap *stdmultimap2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
+ if(!CheckEqualContainers(shmmap2, stdmap2)) return 1;
+ if(!CheckEqualContainers(shmmultimap2, stdmultimap2)) return 1;
+
+ //ordered range insertion
+ //This is really nasty, but we have no other simple choice
+ for(int i = 0; i < 50; ++i){
+ IntType i1(i);
+ IntType i2(i);
+ new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ for(int i = 0; i < 50; ++i){
+ new(&aux_vect2[i])StdValueType(StdKeyType(i), StdMappedType(i));
+ }
+
+ for(int i = 0; i < 50; ++i){
+ IntType i1(i);
+ IntType i2(i);
+ new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ MyShmMap *shmmap3 =
+ segment.template construct<MyShmMap>("MyShmMap3")
+ ( ordered_unique_range
+ , ::boost::make_move_iterator(&aux_vect[0])
+ , ::boost::make_move_iterator(aux_vect + 50)
+ , std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMap *stdmap3 = new MyStdMap(aux_vect2, aux_vect2 + 50);
+
+ MyShmMultiMap *shmmultimap3 =
+ segment.template construct<MyShmMultiMap>("MyShmMultiMap3")
+ ( ordered_range
+ , ::boost::make_move_iterator(&aux_vect3[0])
+ , ::boost::make_move_iterator(aux_vect3 + 50)
+ , std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiMap *stdmultimap3 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
+
+ if(!CheckEqualContainers(shmmap3, stdmap3)){
+ std::cout << "Error in construct<MyShmMap>(MyShmMap3)" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultimap3, stdmultimap3)){
+ std::cout << "Error in construct<MyShmMultiMap>(MyShmMultiMap3)" << std::endl;
+ return 1;
+ }
+
+ segment.destroy_ptr(shmmap2);
+ segment.destroy_ptr(shmmultimap2);
+ delete stdmap2;
+ delete stdmultimap2;
+ segment.destroy_ptr(shmmap3);
+ segment.destroy_ptr(shmmultimap3);
+ delete stdmap3;
+ delete stdmultimap3;
+ }
+ {
+ //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::move(i1), boost::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::move(i1), boost::move(i2));
+ }
+
+ for(int i = 0; i < max; ++i){
+ shmmap->insert(boost::move(aux_vect[i]));
+ stdmap->insert(StdPairType(i, i));
+ shmmultimap->insert(boost::move(aux_vect3[i]));
+ stdmultimap->insert(StdPairType(i, i));
+ }
+
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+
+ typename MyShmMap::iterator it;
+ typename MyShmMap::const_iterator cit = it;
+ (void)cit;
+
+ 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;
+ }
+ //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){
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+ IntPairType aux_vect3[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ shmmap->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
+ shmmultimap->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::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;
+
+ for(int i = 0, j = static_cast<int>(shmmap->size()); i < j; ++i){
+ shmmap->erase(IntType(i));
+ stdmap->erase(i);
+ shmmultimap->erase(IntType(i));
+ stdmultimap->erase(i);
+ }
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+ }
+ {
+ IntPairType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ IntPairType aux_vect3[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ IntPairType aux_vect4[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect4[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ IntPairType aux_vect5[50];
+ for(int i = 0; i < 50; ++i){
+ IntType i1(-1);
+ IntType i2(-1);
+ new(&aux_vect5[i])IntPairType(boost::move(i1), boost::move(i2));
+ }
+
+ shmmap->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
+ shmmap->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
+ shmmultimap->insert(::boost::make_move_iterator(&aux_vect4[0]), ::boost::make_move_iterator(aux_vect4 + 50));
+ shmmultimap->insert(::boost::make_move_iterator(&aux_vect5[0]), ::boost::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);
+ }
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+
+ shmmap->erase(shmmap->begin()->first);
+ stdmap->erase(stdmap->begin()->first);
+ shmmultimap->erase(shmmultimap->begin()->first);
+ stdmultimap->erase(stdmultimap->begin()->first);
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) 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::move(i1), boost::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::move(i1), boost::move(i2));
+ }
+
+ for(int i = 0; i < max; ++i){
+ shmmap->insert(boost::move(aux_vect[i]));
+ stdmap->insert(StdPairType(i, i));
+ shmmultimap->insert(boost::move(aux_vect3[i]));
+ stdmultimap->insert(StdPairType(i, i));
+ }
+
+ if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
+
+ for(int i = 0; i < max; ++i){
+ IntPairType intpair;
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ }
+ shmmap->insert(shmmap->begin(), boost::move(intpair));
+ stdmap->insert(stdmap->begin(), StdPairType(i, i));
+ //PrintContainers(shmmap, stdmap);
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ }
+ shmmultimap->insert(shmmultimap->begin(), boost::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::move(i1), boost::move(i2));
+ }
+ shmmap->insert(shmmap->end(), boost::move(intpair));
+ stdmap->insert(stdmap->end(), StdPairType(i, i));
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ }
+ shmmultimap->insert(shmmultimap->end(), boost::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::move(i1), boost::move(i2));
+ }
+ shmmap->insert(shmmap->lower_bound(IntType(i)), boost::move(intpair));
+ stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
+ //PrintContainers(shmmap, stdmap);
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ }
+ {
+ IntType i1(i);
+ shmmultimap->insert(shmmultimap->lower_bound(boost::move(i1)), boost::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::move(i1), boost::move(i2));
+ }
+ {
+ IntType i1(i);
+ shmmap->insert(shmmap->upper_bound(boost::move(i1)), boost::move(intpair));
+ stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
+ }
+ //PrintContainers(shmmap, stdmap);
+ {
+ IntType i1(i);
+ IntType i2(i);
+ new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ }
+ {
+ IntType i1(i);
+ shmmultimap->insert(shmmultimap->upper_bound(boost::move(i1)), boost::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::move(i1), boost::move(i2));
+ }
+ shmmap->insert(boost::move(intpair));
+ {
+ IntType i1(i), i2(i);
+ new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ }
+ shmmultimap->insert(boost::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");
+ delete stdmap;
+ segment.destroy_ptr(shmmultimap);
+ delete stdmultimap;
+
+ segment.shrink_to_fit_indexes();
+
+ if(!segment.all_memory_deallocated())
+ return 1;
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+template<class ManagedSharedMemory
+ ,class MyShmMap
+ ,class MyStdMap
+ ,class MyShmMultiMap
+ ,class MyStdMultiMap>
+int map_test_copyable ()
+{
+ typedef typename MyShmMap::key_type IntType;
+ 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();
+ const int max = 100;
+
+ try{
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ ManagedSharedMemory segment(create_only, shMemName, memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmMap *shmmap =
+ segment.template construct<MyShmMap>("MyShmMap")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMap *stdmap = new MyStdMap;
+
+ MyShmMultiMap *shmmultimap =
+ segment.template construct<MyShmMultiMap>("MyShmMultiMap")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiMap *stdmultimap = new MyStdMultiMap;
+
+ int i;
+ for(i = 0; i < max; ++i){
+ {
+ IntType i1(i), i2(i);
+ IntPairType intpair1(boost::move(i1), boost::move(i2));
+ shmmap->insert(boost::move(intpair1));
+ stdmap->insert(StdPairType(i, i));
+ }
+ {
+ IntType i1(i), i2(i);
+ IntPairType intpair2(boost::move(i1), boost::move(i2));
+ shmmultimap->insert(boost::move(intpair2));
+ stdmultimap->insert(StdPairType(i, i));
+ }
+ }
+ if(!CheckEqualContainers(shmmap, stdmap)) return 1;
+ if(!CheckEqualContainers(shmmultimap, stdmultimap)) return 1;
+
+ {
+ //Now, test copy constructor
+ MyShmMap shmmapcopy(*shmmap);
+ MyStdMap stdmapcopy(*stdmap);
+ MyShmMultiMap shmmmapcopy(*shmmultimap);
+ MyStdMultiMap stdmmapcopy(*stdmultimap);
+
+ if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
+ return 1;
+ if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
+ return 1;
+
+ //And now assignment
+ shmmapcopy = *shmmap;
+ stdmapcopy = *stdmap;
+ shmmmapcopy = *shmmultimap;
+ stdmmapcopy = *stdmultimap;
+
+ if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
+ return 1;
+ if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
+ return 1;
+ delete stdmap;
+ delete stdmultimap;
+ segment.destroy_ptr(shmmap);
+ segment.destroy_ptr(shmmultimap);
+ }
+ segment.shrink_to_fit_indexes();
+
+ if(!segment.all_memory_deallocated())
+ return 1;
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_MAP_TEST_HEADER
diff --git a/src/boost/libs/interprocess/test/mapped_file_test.cpp b/src/boost/libs/interprocess/test/mapped_file_test.cpp
new file mode 100644
index 000000000..9d19977aa
--- /dev/null
+++ b/src/boost/libs/interprocess/test/mapped_file_test.cpp
@@ -0,0 +1,100 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined(BOOST_INTERPROCESS_MAPPED_FILES)
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#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>
+#include <cstring>
+#include <string>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+static const std::size_t FileSize = 1000;
+inline std::string get_filename()
+{
+ std::string ret (ipcdetail::get_temporary_path());
+ ret += "/";
+ ret += test::get_process_id_name();
+ return ret;
+}
+
+struct file_destroyer
+{
+ ~file_destroyer()
+ {
+ //The last destructor will destroy the file
+ file_mapping::remove(get_filename().c_str());
+ }
+};
+
+//This wrapper is necessary to have a common constructor
+//in generic named_creation_template functions
+class mapped_file_creation_test_wrapper
+ : public file_destroyer
+ , public boost::interprocess::ipcdetail::managed_open_or_create_impl
+ <boost::interprocess::ipcdetail::file_wrapper, 0, true, false>
+{
+ typedef boost::interprocess::ipcdetail::managed_open_or_create_impl
+ <boost::interprocess::ipcdetail::file_wrapper, 0, true, false> mapped_file;
+ public:
+ mapped_file_creation_test_wrapper(boost::interprocess::create_only_t)
+ : mapped_file(boost::interprocess::create_only, get_filename().c_str(), FileSize, read_write, 0, permissions())
+ {}
+
+ mapped_file_creation_test_wrapper(boost::interprocess::open_only_t)
+ : mapped_file(boost::interprocess::open_only, get_filename().c_str(), read_write, 0)
+ {}
+
+ mapped_file_creation_test_wrapper(boost::interprocess::open_or_create_t)
+ : mapped_file(boost::interprocess::open_or_create, get_filename().c_str(), FileSize, read_write, 0, permissions())
+ {}
+};
+
+int main ()
+{
+ typedef boost::interprocess::ipcdetail::managed_open_or_create_impl
+ <boost::interprocess::ipcdetail::file_wrapper, 0, true, false> mapped_file;
+ file_mapping::remove(get_filename().c_str());
+ test::test_named_creation<mapped_file_creation_test_wrapper>();
+
+ //Create and get name, size and address
+ {
+ mapped_file file1(create_only, get_filename().c_str(), FileSize, read_write, 0, permissions());
+
+ //Overwrite all memory
+ std::memset(file1.get_user_address(), 0, file1.get_user_size());
+
+ //Now test move semantics
+ mapped_file move_ctor(boost::move(file1));
+ mapped_file move_assign;
+ move_assign = boost::move(move_ctor);
+ }
+// file_mapping::remove(get_filename().c_str());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#else //#if !defined(BOOST_INTERPROCESS_MAPPED_FILES)
+
+int main()
+{
+ return 0;
+}
+
+#endif//#if !defined(BOOST_INTERPROCESS_MAPPED_FILES)
diff --git a/src/boost/libs/interprocess/test/memory_algorithm_test.cpp b/src/boost/libs/interprocess/test/memory_algorithm_test.cpp
new file mode 100644
index 000000000..9210640a4
--- /dev/null
+++ b/src/boost/libs/interprocess/test/memory_algorithm_test.cpp
@@ -0,0 +1,91 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/indexes/null_index.hpp>
+#include <boost/interprocess/sync/mutex_family.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/move/detail/type_traits.hpp> //make_unsigned, alignment_of
+#include "memory_algorithm_test_template.hpp"
+#include <iostream>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+const int Memsize = 16384;
+const char *const shMemName = test::get_process_id_name();
+
+int test_simple_seq_fit()
+{
+ //A shared memory with simple sequential fit algorithm
+ typedef basic_managed_shared_memory
+ <char
+ ,simple_seq_fit<mutex_family>
+ ,null_index
+ > my_managed_shared_memory;
+
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ my_managed_shared_memory segment(create_only, shMemName, Memsize);
+
+ //Now take the segment manager and launch memory test
+ if(!test::test_all_allocation(*segment.get_segment_manager())){
+ return 1;
+ }
+ return 0;
+}
+
+template<std::size_t Alignment>
+int test_rbtree_best_fit()
+{
+ //A shared memory with red-black tree best fit algorithm
+ typedef basic_managed_shared_memory
+ <char
+ ,rbtree_best_fit<mutex_family, offset_ptr<void>, Alignment>
+ ,null_index
+ > my_managed_shared_memory;
+
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ my_managed_shared_memory segment(create_only, shMemName, Memsize);
+
+ //Now take the segment manager and launch memory test
+ if(!test::test_all_allocation(*segment.get_segment_manager())){
+ return 1;
+ }
+ return 0;
+}
+
+int main ()
+{
+ const std::size_t void_ptr_align = ::boost::container::dtl::alignment_of<offset_ptr<void> >::value;
+
+ if(test_simple_seq_fit()){
+ return 1;
+ }
+ if(test_rbtree_best_fit<void_ptr_align>()){
+ return 1;
+ }
+ if(test_rbtree_best_fit<2*void_ptr_align>()){
+ return 1;
+ }
+ if(test_rbtree_best_fit<4*void_ptr_align>()){
+ return 1;
+ }
+
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/memory_algorithm_test_template.hpp b/src/boost/libs/interprocess/test/memory_algorithm_test_template.hpp
new file mode 100644
index 000000000..10e880e7f
--- /dev/null
+++ b/src/boost/libs/interprocess/test/memory_algorithm_test_template.hpp
@@ -0,0 +1,1036 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER
+#define BOOST_INTERPROCESS_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+
+#include <boost/interprocess/containers/vector.hpp>
+
+#include <vector>
+#include <iostream>
+#include <new> //std::nothrow
+#include <cstring> //std::memset
+
+namespace boost { namespace interprocess { namespace test {
+
+enum deallocation_type { DirectDeallocation, InverseDeallocation, MixedDeallocation, EndDeallocationType };
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the inverse order
+template<class Allocator>
+bool test_allocation(Allocator &a)
+{
+ for( deallocation_type t = DirectDeallocation
+ ; t != EndDeallocationType
+ ; t = (deallocation_type)((int)t + 1)){
+ std::vector<void*> buffers;
+ typename Allocator::size_type free_memory = a.get_free_memory();
+
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers.push_back(ptr);
+ }
+
+ switch(t){
+ case DirectDeallocation:
+ {
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ a.deallocate(buffers[j]);
+ }
+ }
+ break;
+ case InverseDeallocation:
+ {
+ for(int j = (int)buffers.size()
+ ;j--
+ ;){
+ a.deallocate(buffers[j]);
+ }
+ }
+ break;
+ case MixedDeallocation:
+ {
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+ return true;
+}
+
+//This test allocates until there is no more memory
+//and after that tries to shrink all the buffers to the
+//half of the original size
+template<class Allocator>
+bool test_allocation_shrink(Allocator &a)
+{
+ std::vector<void*> buffers;
+
+ //Allocate buffers with extra memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i*2, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers.push_back(ptr);
+ }
+
+ //Now shrink to half
+ for(int i = 0, max = (int)buffers.size()
+ ;i < max
+ ; ++i){
+ typename Allocator::size_type received_size;
+ char *reuse = static_cast<char*>(buffers[i]);
+ if(a.template allocation_command<char>
+ ( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, i*2
+ , received_size = i, reuse)){
+ if(received_size > std::size_t(i*2)){
+ return false;
+ }
+ if(received_size < std::size_t(i)){
+ return false;
+ }
+ std::memset(buffers[i], 0, a.size(buffers[i]));
+ }
+ }
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+
+ return a.all_memory_deallocated() && a.check_sanity();
+}
+
+//This test allocates until there is no more memory
+//and after that tries to expand all the buffers to
+//avoid the wasted internal fragmentation
+template<class Allocator>
+bool test_allocation_expand(Allocator &a)
+{
+ std::vector<void*> buffers;
+
+ //Allocate buffers with extra memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers.push_back(ptr);
+ }
+
+ //Now try to expand to the double of the size
+ for(int i = 0, max = (int)buffers.size()
+ ;i < max
+ ;++i){
+ typename Allocator::size_type received_size;
+ std::size_t min_size = i+1;
+ std::size_t preferred_size = i*2;
+ preferred_size = min_size > preferred_size ? min_size : preferred_size;
+
+ char *reuse = static_cast<char*>(buffers[i]);
+ while(a.template allocation_command<char>
+ ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
+ , received_size = preferred_size, reuse)){
+ //Check received size is bigger than minimum
+ if(received_size < min_size){
+ return false;
+ }
+ //Now, try to expand further
+ min_size = received_size+1;
+ preferred_size = min_size*2;
+ }
+ }
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+
+ return a.all_memory_deallocated() && a.check_sanity();
+}
+
+//This test allocates until there is no more memory
+//and after that tries to expand all the buffers to
+//avoid the wasted internal fragmentation
+template<class Allocator>
+bool test_allocation_shrink_and_expand(Allocator &a)
+{
+ std::vector<void*> buffers;
+ std::vector<typename Allocator::size_type> received_sizes;
+ std::vector<bool> size_reduced;
+
+ //Allocate buffers wand store received sizes
+ for(int i = 0; true; ++i){
+ typename Allocator::size_type received_size;
+ char *reuse = 0;
+ void *ptr = a.template allocation_command<char>
+ ( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, i, received_size = i*2, reuse);
+ if(!ptr){
+ ptr = a.template allocation_command<char>
+ ( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, 1, received_size = i*2, reuse);
+ if(!ptr)
+ break;
+ }
+ buffers.push_back(ptr);
+ received_sizes.push_back(received_size);
+ }
+
+ //Now shrink to half
+ for(int i = 0, max = (int)buffers.size()
+ ; i < max
+ ; ++i){
+ typename Allocator::size_type received_size;
+ char *reuse = static_cast<char*>(buffers[i]);
+ if(a.template allocation_command<char>
+ ( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_sizes[i]
+ , received_size = i, reuse)){
+ if(received_size > std::size_t(received_sizes[i])){
+ return false;
+ }
+ if(received_size < std::size_t(i)){
+ return false;
+ }
+ size_reduced.push_back(received_size != received_sizes[i]);
+ }
+ }
+
+ //Now try to expand to the original size
+ for(int i = 0, max = (int)buffers.size()
+ ;i < max
+ ;++i){
+ typename Allocator::size_type received_size;
+ std::size_t request_size = received_sizes[i];
+ char *reuse = static_cast<char*>(buffers[i]);
+ if(a.template allocation_command<char>
+ ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, request_size
+ , received_size = request_size, reuse)){
+ if(received_size != received_sizes[i]){
+ return false;
+ }
+ }
+ else{
+ return false;
+ }
+ }
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+
+ return a.all_memory_deallocated() && a.check_sanity();
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates the odd buffers to
+//make room for expansions. The expansion will probably
+//success since the deallocation left room for that.
+template<class Allocator>
+bool test_allocation_deallocation_expand(Allocator &a)
+{
+ std::vector<void*> buffers;
+
+ //Allocate buffers with extra memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers.push_back(ptr);
+ }
+
+ //Now deallocate the half of the blocks
+ //so expand maybe can merge new free blocks
+ for(int i = 0, max = (int)buffers.size()
+ ;i < max
+ ;++i){
+ if(i%2){
+ a.deallocate(buffers[i]);
+ buffers[i] = 0;
+ }
+ }
+
+ //Now try to expand to the double of the size
+ for(int i = 0, max = (int)buffers.size()
+ ;i < max
+ ;++i){
+ //
+ if(buffers[i]){
+ typename Allocator::size_type received_size;
+ std::size_t min_size = i+1;
+ std::size_t preferred_size = i*2;
+ preferred_size = min_size > preferred_size ? min_size : preferred_size;
+
+ char *reuse = static_cast<char*>(buffers[i]);
+ while(a.template allocation_command<char>
+ ( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
+ , received_size = preferred_size, reuse)){
+ //Check received size is bigger than minimum
+ if(received_size < min_size){
+ return false;
+ }
+ //Now, try to expand further
+ min_size = received_size+1;
+ preferred_size = min_size*2;
+ }
+ }
+ }
+
+ //Now erase null values from the vector
+ buffers.erase( std::remove(buffers.begin(), buffers.end(), static_cast<void*>(0))
+ , buffers.end());
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+
+ return a.all_memory_deallocated() && a.check_sanity();
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all except the last.
+//If the allocation algorithm is a bottom-up algorithm
+//the last buffer will be in the end of the segment.
+//Then the test will start expanding backwards, until
+//the buffer fills all the memory
+template<class Allocator>
+bool test_allocation_with_reuse(Allocator &a)
+{
+ //We will repeat this test for different sized elements
+ for(int sizeof_object = 1; sizeof_object < 20; ++sizeof_object){
+ std::vector<void*> buffers;
+
+ //Allocate buffers with extra memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i*sizeof_object, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers.push_back(ptr);
+ }
+
+ //Now deallocate all except the latest
+ //Now try to expand to the double of the sizeof_object
+ for(int i = 0, max = (int)buffers.size() - 1
+ ;i < max
+ ;++i){
+ a.deallocate(buffers[i]);
+ }
+
+ //Save the unique buffer and clear vector
+ void *ptr = buffers.back();
+ buffers.clear();
+
+ //Now allocate with reuse
+ typename Allocator::size_type received_size = 0;
+ for(int i = 0; true; ++i){
+ std::size_t min_size = (received_size + 1);
+ std::size_t prf_size = (received_size + (i+1)*2);
+ void *reuse = ptr;
+ void *ret = a.raw_allocation_command
+ ( boost::interprocess::expand_bwd | boost::interprocess::nothrow_allocation, min_size
+ , received_size = prf_size, reuse, sizeof_object);
+ if(!ret)
+ break;
+ //If we have memory, this must be a buffer reuse
+ if(!reuse)
+ return 1;
+ if(received_size < min_size)
+ return 1;
+ ptr = ret;
+ }
+ //There is only a single block so deallocate it
+ a.deallocate(ptr);
+
+ if(!a.all_memory_deallocated() || !a.check_sanity())
+ return false;
+ }
+ return true;
+}
+
+
+//This test allocates memory with different alignments
+//and checks returned memory is aligned.
+template<class Allocator>
+bool test_aligned_allocation(Allocator &a)
+{
+ //Allocate aligned buffers in a loop
+ //and then deallocate it
+ bool continue_loop = true;
+ for(unsigned int i = 1; continue_loop; i <<= 1){
+ for(unsigned int j = 1; true; j <<= 1){
+ void *ptr = a.allocate_aligned(i-1, j, std::nothrow);
+ if(!ptr){
+ if(j == 1)
+ continue_loop = false;
+ break;
+ }
+
+ if(((std::size_t)ptr & (j - 1)) != 0)
+ return false;
+ a.deallocate(ptr);
+ if(!a.all_memory_deallocated() || !a.check_sanity()){
+ return false;
+ }
+ }
+ }
+
+ return a.all_memory_deallocated() && a.check_sanity();
+}
+
+//This test allocates memory with different alignments
+//and checks returned memory is aligned.
+template<class Allocator>
+bool test_continuous_aligned_allocation(Allocator &a)
+{
+ std::vector<void*> buffers;
+ //Allocate aligned buffers in a loop
+ //and then deallocate it
+ bool continue_loop = true;
+ for(unsigned i = 1; continue_loop && i; i <<= 1){
+ for(unsigned int j = 1; j; j <<= 1){
+ for(bool any_allocated = false; 1;){
+ void *ptr = a.allocate_aligned(i-1, j, std::nothrow);
+ buffers.push_back(ptr);
+ if(!ptr){
+ if(j == 1 && !any_allocated){
+ continue_loop = false;
+ }
+ break;
+ }
+ else{
+ any_allocated = true;
+ }
+
+ if(((std::size_t)ptr & (j - 1)) != 0)
+ return false;
+ }
+ //Deallocate all
+ for(unsigned int k = (int)buffers.size(); k--;){
+ a.deallocate(buffers[k]);
+ }
+ buffers.clear();
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+ if(!continue_loop)
+ break;
+ }
+ }
+
+ return a.all_memory_deallocated() && a.check_sanity();
+}
+
+//This test allocates memory, writes it with a non-zero value and
+//tests zero_free_memory initializes to zero for the next allocation
+template<class Allocator>
+bool test_clear_free_memory(Allocator &a)
+{
+ std::vector<void*> buffers;
+
+ //Allocate memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 1, size);
+ buffers.push_back(ptr);
+ }
+
+ //Mark it
+ for(int i = 0, max = buffers.size(); i < max; ++i){
+ std::memset(buffers[i], 1, i);
+ }
+
+ //Deallocate all
+ for(int j = (int)buffers.size()
+ ;j--
+ ;){
+ a.deallocate(buffers[j]);
+ }
+ buffers.clear();
+
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+
+ //Now clear all free memory
+ a.zero_free_memory();
+
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+
+ //Now test all allocated memory is zero
+ //Allocate memory
+ const char *first_addr = 0;
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ if(i == 0){
+ first_addr = (char*)ptr;
+ }
+ std::size_t memsize = a.size(ptr);
+ buffers.push_back(ptr);
+
+ for(int j = 0; j < (int)memsize; ++j){
+ if(static_cast<char*>((char*)ptr)[j]){
+ std::cout << "Zero memory test failed. in buffer " << i
+ << " byte " << j << " first address " << (void*) first_addr << " offset " << ((char*)ptr+j) - (char*)first_addr << " memsize: " << memsize << std::endl;
+ return false;
+ }
+ }
+ }
+
+ //Deallocate all
+ for(int j = (int)buffers.size()
+ ;j--
+ ;){
+ a.deallocate(buffers[j]);
+ }
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+
+ return true;
+}
+
+
+//This test uses tests grow and shrink_to_fit functions
+template<class Allocator>
+bool test_grow_shrink_to_fit(Allocator &a)
+{
+ std::vector<void*> buffers;
+
+ typename Allocator::size_type original_size = a.get_size();
+ typename Allocator::size_type original_free = a.get_free_memory();
+
+ a.shrink_to_fit();
+
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+
+ typename Allocator::size_type shrunk_size = a.get_size();
+ typename Allocator::size_type shrunk_free_memory = a.get_free_memory();
+ if(shrunk_size != a.get_min_size())
+ return 1;
+
+ a.grow(original_size - shrunk_size);
+
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+
+ if(original_size != a.get_size())
+ return false;
+ if(original_free != a.get_free_memory())
+ return false;
+
+ //Allocate memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers.push_back(ptr);
+ }
+
+ //Now deallocate the half of the blocks
+ //so expand maybe can merge new free blocks
+ for(int i = 0, max = (int)buffers.size()
+ ;i < max
+ ;++i){
+ if(i%2){
+ a.deallocate(buffers[i]);
+ buffers[i] = 0;
+ }
+ }
+
+ //Deallocate the rest of the blocks
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%5)*((int)buffers.size())/4;
+ if(pos == int(buffers.size()))
+ --pos;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ typename Allocator::size_type old_free = a.get_free_memory();
+ a.shrink_to_fit();
+ if(!a.check_sanity()) return false;
+ if(original_size < a.get_size()) return false;
+ if(old_free < a.get_free_memory()) return false;
+
+ a.grow(original_size - a.get_size());
+
+ if(!a.check_sanity()) return false;
+ if(original_size != a.get_size()) return false;
+ if(old_free != a.get_free_memory()) return false;
+ }
+
+ //Now shrink it to the maximum
+ a.shrink_to_fit();
+
+ if(a.get_size() != a.get_min_size())
+ return 1;
+
+ if(shrunk_free_memory != a.get_free_memory())
+ return 1;
+
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+
+ a.grow(original_size - shrunk_size);
+
+ if(original_size != a.get_size())
+ return false;
+ if(original_free != a.get_free_memory())
+ return false;
+
+ if(!a.all_memory_deallocated() && a.check_sanity())
+ return false;
+ return true;
+}
+
+//This test allocates multiple values until there is no more memory
+//and after that deallocates all in the inverse order
+template<class Allocator>
+bool test_many_equal_allocation(Allocator &a)
+{
+ for( deallocation_type t = DirectDeallocation
+ ; t != EndDeallocationType
+ ; t = (deallocation_type)((int)t + 1)){
+ typename Allocator::size_type free_memory = a.get_free_memory();
+
+ std::vector<void*> buffers2;
+
+ //Allocate buffers with extra memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ if(!a.check_sanity())
+ return false;
+ buffers2.push_back(ptr);
+ }
+
+ //Now deallocate the half of the blocks
+ //so expand maybe can merge new free blocks
+ for(int i = 0, max = (int)buffers2.size()
+ ;i < max
+ ;++i){
+ if(i%2){
+ a.deallocate(buffers2[i]);
+ buffers2[i] = 0;
+ }
+ }
+
+ if(!a.check_sanity())
+ return false;
+
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
+ std::vector<void*> buffers;
+ for(int i = 0; true; ++i){
+ multiallocation_chain chain;
+ a.allocate_many(std::nothrow, i+1, (i+1)*2, chain);
+ if(chain.empty())
+ break;
+
+ typename multiallocation_chain::size_type n = chain.size();
+ while(!chain.empty()){
+ buffers.push_back(ipcdetail::to_raw_pointer(chain.pop_front()));
+ }
+ if(n != std::size_t((i+1)*2))
+ return false;
+ }
+
+ if(!a.check_sanity())
+ return false;
+
+ switch(t){
+ case DirectDeallocation:
+ {
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ a.deallocate(buffers[j]);
+ }
+ }
+ break;
+ case InverseDeallocation:
+ {
+ for(int j = (int)buffers.size()
+ ;j--
+ ;){
+ a.deallocate(buffers[j]);
+ }
+ }
+ break;
+ case MixedDeallocation:
+ {
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ //Deallocate the rest of the blocks
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers2.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers2.size())/4;
+ a.deallocate(buffers2[pos]);
+ buffers2.erase(buffers2.begin()+pos);
+ }
+
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+ return true;
+}
+
+//This test allocates multiple values until there is no more memory
+//and after that deallocates all in the inverse order
+template<class Allocator>
+bool test_many_different_allocation(Allocator &a)
+{
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
+ const std::size_t ArraySize = 11;
+ typename Allocator::size_type requested_sizes[ArraySize];
+ for(std::size_t i = 0; i < ArraySize; ++i){
+ requested_sizes[i] = 4*i;
+ }
+
+ for( deallocation_type t = DirectDeallocation
+ ; t != EndDeallocationType
+ ; t = (deallocation_type)((int)t + 1)){
+ typename Allocator::size_type free_memory = a.get_free_memory();
+
+ std::vector<void*> buffers2;
+
+ //Allocate buffers with extra memory
+ for(int i = 0; true; ++i){
+ void *ptr = a.allocate(i, std::nothrow);
+ if(!ptr)
+ break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
+ buffers2.push_back(ptr);
+ }
+
+ //Now deallocate the half of the blocks
+ //so expand maybe can merge new free blocks
+ for(int i = 0, max = (int)buffers2.size()
+ ;i < max
+ ;++i){
+ if(i%2){
+ a.deallocate(buffers2[i]);
+ buffers2[i] = 0;
+ }
+ }
+
+ std::vector<void*> buffers;
+ for(int i = 0; true; ++i){
+ multiallocation_chain chain;
+ a.allocate_many(std::nothrow, requested_sizes, ArraySize, 1, chain);
+ if(chain.empty())
+ break;
+ typename multiallocation_chain::size_type n = chain.size();
+ while(!chain.empty()){
+ buffers.push_back(ipcdetail::to_raw_pointer(chain.pop_front()));
+ }
+ if(n != ArraySize)
+ return false;
+ }
+
+ switch(t){
+ case DirectDeallocation:
+ {
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ a.deallocate(buffers[j]);
+ }
+ }
+ break;
+ case InverseDeallocation:
+ {
+ for(int j = (int)buffers.size()
+ ;j--
+ ;){
+ a.deallocate(buffers[j]);
+ }
+ }
+ break;
+ case MixedDeallocation:
+ {
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ //Deallocate the rest of the blocks
+
+ //Deallocate it in non sequential order
+ for(int j = 0, max = (int)buffers2.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers2.size())/4;
+ a.deallocate(buffers2[pos]);
+ buffers2.erase(buffers2.begin()+pos);
+ }
+
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+ return true;
+}
+
+//This test allocates multiple values until there is no more memory
+//and after that deallocates all in the inverse order
+template<class Allocator>
+bool test_many_deallocation(Allocator &a)
+{
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
+
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
+ const std::size_t ArraySize = 11;
+ vector<multiallocation_chain> buffers;
+ typename Allocator::size_type requested_sizes[ArraySize];
+ for(std::size_t i = 0; i < ArraySize; ++i){
+ requested_sizes[i] = 4*i;
+ }
+ typename Allocator::size_type free_memory = a.get_free_memory();
+
+ {
+ for(int i = 0; true; ++i){
+ multiallocation_chain chain;
+ a.allocate_many(std::nothrow, requested_sizes, ArraySize, 1, chain);
+ if(chain.empty())
+ break;
+ buffers.push_back(boost::move(chain));
+ }
+ for(int i = 0, max = (int)buffers.size(); i != max; ++i){
+ a.deallocate_many(buffers[i]);
+ }
+ buffers.clear();
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+
+ {
+ for(int i = 0; true; ++i){
+ multiallocation_chain chain;
+ a.allocate_many(std::nothrow, i*4, ArraySize, chain);
+ if(chain.empty())
+ break;
+ buffers.push_back(boost::move(chain));
+ }
+ for(int i = 0, max = (int)buffers.size(); i != max; ++i){
+ a.deallocate_many(buffers[i]);
+ }
+ buffers.clear();
+
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+
+ return true;
+}
+
+
+//This function calls all tests
+template<class Allocator>
+bool test_all_allocation(Allocator &a)
+{
+ std::cout << "Starting test_allocation. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_allocation(a)){
+ std::cout << "test_allocation_direct_deallocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_many_equal_allocation. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_many_equal_allocation(a)){
+ std::cout << "test_many_equal_allocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_many_different_allocation. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_many_different_allocation(a)){
+ std::cout << "test_many_different_allocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ if(!test_many_deallocation(a)){
+ std::cout << "test_many_deallocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_allocation_shrink. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_allocation_shrink(a)){
+ std::cout << "test_allocation_shrink failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ if(!test_allocation_shrink_and_expand(a)){
+ std::cout << "test_allocation_shrink_and_expand failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_allocation_expand. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_allocation_expand(a)){
+ std::cout << "test_allocation_expand failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_allocation_deallocation_expand. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_allocation_deallocation_expand(a)){
+ std::cout << "test_allocation_deallocation_expand failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_allocation_with_reuse. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_allocation_with_reuse(a)){
+ std::cout << "test_allocation_with_reuse failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_aligned_allocation. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_aligned_allocation(a)){
+ std::cout << "test_aligned_allocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_continuous_aligned_allocation. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_continuous_aligned_allocation(a)){
+ std::cout << "test_continuous_aligned_allocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_clear_free_memory. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_clear_free_memory(a)){
+ std::cout << "test_clear_free_memory failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_grow_shrink_to_fit. Class: "
+ << typeid(a).name() << std::endl;
+
+ if(!test_grow_shrink_to_fit(a)){
+ std::cout << "test_grow_shrink_to_fit failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER
+
diff --git a/src/boost/libs/interprocess/test/message_queue_test.cpp b/src/boost/libs/interprocess/test/message_queue_test.cpp
new file mode 100644
index 000000000..fe76cad57
--- /dev/null
+++ b/src/boost/libs/interprocess/test/message_queue_test.cpp
@@ -0,0 +1,376 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/ipc/message_queue.hpp>
+#include <boost/interprocess/managed_external_buffer.hpp>
+#include <boost/interprocess/managed_heap_memory.hpp>
+#include <boost/interprocess/containers/map.hpp>
+#include <boost/interprocess/containers/set.hpp>
+#include <boost/interprocess/allocators/node_allocator.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+
+#include <cstddef>
+#include <memory>
+#include <iostream>
+#include <vector>
+#include <stdexcept>
+#include <limits>
+
+#include "get_process_id_name.hpp"
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// This example tests the process shared message queue. //
+// //
+////////////////////////////////////////////////////////////////////////////////
+
+using namespace boost::interprocess;
+
+//This test inserts messages with different priority and marks them with a
+//time-stamp to check if receiver obtains highest priority messages first and
+//messages with same priority are received in fifo order
+bool test_priority_order()
+{
+ message_queue::remove(test::get_process_id_name());
+ {
+ message_queue mq1
+ (open_or_create, test::get_process_id_name(), 100, sizeof(std::size_t)),
+ mq2
+ (open_or_create, test::get_process_id_name(), 100, sizeof(std::size_t));
+
+ //We test that the queue is ordered by priority and in the
+ //same priority, is a FIFO
+ message_queue::size_type recvd = 0;
+ unsigned int priority = 0;
+ std::size_t tstamp;
+ unsigned int priority_prev;
+ std::size_t tstamp_prev;
+
+ //We will send 100 message with priority 0-9
+ //The message will contain the timestamp of the message
+ for(std::size_t i = 0; i < 100; ++i){
+ tstamp = i;
+ mq1.send(&tstamp, sizeof(tstamp), (unsigned int)(i%10));
+ }
+
+ priority_prev = (std::numeric_limits<unsigned int>::max)();
+ tstamp_prev = 0;
+
+ //Receive all messages and test those are ordered
+ //by priority and by FIFO in the same priority
+ for(std::size_t i = 0; i < 100; ++i){
+ mq1.receive(&tstamp, sizeof(tstamp), recvd, priority);
+ if(priority > priority_prev)
+ return false;
+ if(priority == priority_prev &&
+ tstamp <= tstamp_prev){
+ return false;
+ }
+ priority_prev = priority;
+ tstamp_prev = tstamp;
+ }
+
+ //Now retry it with different priority order
+ for(std::size_t i = 0; i < 100; ++i){
+ tstamp = i;
+ mq1.send(&tstamp, sizeof(tstamp), (unsigned int)(9 - i%10));
+ }
+
+ priority_prev = (std::numeric_limits<unsigned int>::max)();
+ tstamp_prev = 0;
+
+ //Receive all messages and test those are ordered
+ //by priority and by FIFO in the same priority
+ for(std::size_t i = 0; i < 100; ++i){
+ mq1.receive(&tstamp, sizeof(tstamp), recvd, priority);
+ if(priority > priority_prev)
+ return false;
+ if(priority == priority_prev &&
+ tstamp <= tstamp_prev){
+ return false;
+ }
+ priority_prev = priority;
+ tstamp_prev = tstamp;
+ }
+ }
+ message_queue::remove(test::get_process_id_name());
+ return true;
+}
+
+//[message_queue_test_test_serialize_db
+//This test creates a in memory data-base using Interprocess machinery and
+//serializes it through a message queue. Then rebuilds the data-base in
+//another buffer and checks it against the original data-base
+bool test_serialize_db()
+{
+ //Typedef data to create a Interprocess map
+ typedef std::pair<const std::size_t, std::size_t> MyPair;
+ typedef std::less<std::size_t> MyLess;
+ typedef node_allocator<MyPair, managed_external_buffer::segment_manager>
+ node_allocator_t;
+ typedef map<std::size_t,
+ std::size_t,
+ std::less<std::size_t>,
+ node_allocator_t>
+ MyMap;
+
+ //Some constants
+ const std::size_t BufferSize = 65536;
+ const std::size_t MaxMsgSize = 100;
+
+ //Allocate a memory buffer to hold the destiny database using vector<char>
+ std::vector<char> buffer_destiny(BufferSize, 0);
+
+ message_queue::remove(test::get_process_id_name());
+ {
+ //Create the message-queues
+ message_queue mq1(create_only, test::get_process_id_name(), 1, MaxMsgSize);
+
+ //Open previously created message-queue simulating other process
+ message_queue mq2(open_only, test::get_process_id_name());
+
+ //A managed heap memory to create the origin database
+ managed_heap_memory db_origin(buffer_destiny.size());
+
+ //Construct the map in the first buffer
+ MyMap *map1 = db_origin.construct<MyMap>("MyMap")
+ (MyLess(),
+ db_origin.get_segment_manager());
+ if(!map1)
+ return false;
+
+ //Fill map1 until is full
+ try{
+ std::size_t i = 0;
+ while(1){
+ (*map1)[i] = i;
+ ++i;
+ }
+ }
+ catch(boost::interprocess::bad_alloc &){}
+
+ //Data control data sending through the message queue
+ std::size_t sent = 0;
+ message_queue::size_type recvd = 0;
+ message_queue::size_type total_recvd = 0;
+ unsigned int priority;
+
+ //Send whole first buffer through the mq1, read it
+ //through mq2 to the second buffer
+ while(1){
+ //Send a fragment of buffer1 through mq1
+ std::size_t bytes_to_send = MaxMsgSize < (db_origin.get_size() - sent) ?
+ MaxMsgSize : (db_origin.get_size() - sent);
+ mq1.send( &static_cast<char*>(db_origin.get_address())[sent]
+ , bytes_to_send
+ , 0);
+ sent += bytes_to_send;
+ //Receive the fragment through mq2 to buffer_destiny
+ mq2.receive( &buffer_destiny[total_recvd]
+ , BufferSize - recvd
+ , recvd
+ , priority);
+ total_recvd += recvd;
+
+ //Check if we have received all the buffer
+ if(total_recvd == BufferSize){
+ break;
+ }
+ }
+
+ //The buffer will contain a copy of the original database
+ //so let's interpret the buffer with managed_external_buffer
+ managed_external_buffer db_destiny(open_only, &buffer_destiny[0], BufferSize);
+
+ //Let's find the map
+ std::pair<MyMap *, managed_external_buffer::size_type> ret = db_destiny.find<MyMap>("MyMap");
+ MyMap *map2 = ret.first;
+
+ //Check if we have found it
+ if(!map2){
+ return false;
+ }
+
+ //Check if it is a single variable (not an array)
+ if(ret.second != 1){
+ return false;
+ }
+
+ //Now let's compare size
+ if(map1->size() != map2->size()){
+ return false;
+ }
+
+ //Now let's compare all db values
+ MyMap::size_type num_elements = map1->size();
+ for(std::size_t i = 0; i < num_elements; ++i){
+ if((*map1)[i] != (*map2)[i]){
+ return false;
+ }
+ }
+
+ //Destroy maps from db-s
+ db_origin.destroy_ptr(map1);
+ db_destiny.destroy_ptr(map2);
+ }
+ message_queue::remove(test::get_process_id_name());
+ return true;
+}
+//]
+
+static const int MsgSize = 10;
+static const int NumMsg = 1000;
+static char msgsend [10];
+static char msgrecv [10];
+
+static boost::interprocess::message_queue *pmessage_queue;
+
+void receiver()
+{
+ boost::interprocess::message_queue::size_type recvd_size;
+ unsigned int priority;
+ int nummsg = NumMsg;
+
+ while(nummsg--){
+ pmessage_queue->receive(msgrecv, MsgSize, recvd_size, priority);
+ }
+}
+
+bool test_buffer_overflow()
+{
+ boost::interprocess::message_queue::remove(test::get_process_id_name());
+ {
+ boost::movelib::unique_ptr<boost::interprocess::message_queue>
+ ptr(new boost::interprocess::message_queue
+ (create_only, test::get_process_id_name(), 10, 10));
+ pmessage_queue = ptr.get();
+
+ //Launch the receiver thread
+ boost::interprocess::ipcdetail::OS_thread_t thread;
+ boost::interprocess::ipcdetail::thread_launch(thread, &receiver);
+ boost::interprocess::ipcdetail::thread_yield();
+
+ int nummsg = NumMsg;
+
+ while(nummsg--){
+ pmessage_queue->send(msgsend, MsgSize, 0);
+ }
+
+ boost::interprocess::ipcdetail::thread_join(thread);
+ }
+ boost::interprocess::message_queue::remove(test::get_process_id_name());
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// test_multi_sender_receiver is based on Alexander (aalutov's)
+// testcase for ticket #9221. Many thanks.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+static boost::interprocess::message_queue *global_queue = 0;
+//We'll send MULTI_NUM_MSG_PER_SENDER messages per sender
+static const int MULTI_NUM_MSG_PER_SENDER = 10000;
+//Message queue message capacity
+static const int MULTI_QUEUE_SIZE = (MULTI_NUM_MSG_PER_SENDER - 1)/MULTI_NUM_MSG_PER_SENDER + 1;
+//We'll launch MULTI_THREAD_COUNT senders and MULTI_THREAD_COUNT receivers
+static const int MULTI_THREAD_COUNT = 10;
+
+static void multisend()
+{
+ char buff;
+ for (int i = 0; i < MULTI_NUM_MSG_PER_SENDER; i++) {
+ global_queue->send(&buff, 1, 0);
+ }
+ global_queue->send(&buff, 0, 0);
+ //std::cout<<"writer thread complete"<<std::endl;
+}
+
+static void multireceive()
+{
+ char buff;
+ size_t size;
+ int received_msgs = 0;
+ unsigned int priority;
+ do {
+ global_queue->receive(&buff, 1, size, priority);
+ ++received_msgs;
+ } while (size > 0);
+ --received_msgs;
+ //std::cout << "reader thread complete, read msgs: " << received_msgs << std::endl;
+}
+
+
+bool test_multi_sender_receiver()
+{
+ bool ret = true;
+ //std::cout << "Testing multi-sender / multi-receiver " << std::endl;
+ try {
+ boost::interprocess::message_queue::remove(test::get_process_id_name());
+ boost::interprocess::message_queue mq
+ (boost::interprocess::open_or_create, test::get_process_id_name(), MULTI_QUEUE_SIZE, 1);
+ global_queue = &mq;
+ std::vector<boost::interprocess::ipcdetail::OS_thread_t> threads(MULTI_THREAD_COUNT*2);
+
+ //Launch senders receiver thread
+ for (int i = 0; i < MULTI_THREAD_COUNT; i++) {
+ boost::interprocess::ipcdetail::thread_launch
+ (threads[i], &multisend);
+ }
+
+ for (int i = 0; i < MULTI_THREAD_COUNT; i++) {
+ boost::interprocess::ipcdetail::thread_launch
+ (threads[MULTI_THREAD_COUNT+i], &multireceive);
+ }
+
+ for (int i = 0; i < MULTI_THREAD_COUNT*2; i++) {
+ boost::interprocess::ipcdetail::thread_join(threads[i]);
+ //std::cout << "Joined thread " << i << std::endl;
+ }
+ }
+ catch (std::exception &e) {
+ std::cout << "error " << e.what() << std::endl;
+ ret = false;
+ }
+ boost::interprocess::message_queue::remove(test::get_process_id_name());
+ return ret;
+}
+
+
+int main ()
+{
+ if(!test_priority_order()){
+ return 1;
+ }
+
+ if(!test_serialize_db()){
+ return 1;
+ }
+
+ if(!test_buffer_overflow()){
+ return 1;
+ }
+
+ if(!test_multi_sender_receiver()){
+ return 1;
+ }
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/movable_int.hpp b/src/boost/libs/interprocess/test/movable_int.hpp
new file mode 100644
index 000000000..3890a4683
--- /dev/null
+++ b/src/boost/libs/interprocess/test/movable_int.hpp
@@ -0,0 +1,293 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_TEST_MOVABLE_INT_HEADER
+#define BOOST_INTERPROCESS_TEST_MOVABLE_INT_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+template<class T>
+struct is_copyable;
+
+template<>
+struct is_copyable<int>
+{
+ static const bool value = true;
+};
+
+
+class movable_int
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int)
+
+ public:
+ movable_int()
+ : m_int(0)
+ {}
+
+ explicit movable_int(int a)
+ : m_int(a)
+ {}
+
+ movable_int(BOOST_RV_REF(movable_int) mmi)
+ : m_int(mmi.m_int)
+ { mmi.m_int = 0; }
+
+ movable_int & operator= (BOOST_RV_REF(movable_int) mmi)
+ { this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
+
+ movable_int & operator= (int i)
+ { this->m_int = i; return *this; }
+
+ bool operator ==(const movable_int &mi) const
+ { return this->m_int == mi.m_int; }
+
+ bool operator !=(const movable_int &mi) const
+ { return this->m_int != mi.m_int; }
+
+ bool operator <(const movable_int &mi) const
+ { return this->m_int < mi.m_int; }
+
+ bool operator <=(const movable_int &mi) const
+ { return this->m_int <= mi.m_int; }
+
+ bool operator >=(const movable_int &mi) const
+ { return this->m_int >= mi.m_int; }
+
+ bool operator >(const movable_int &mi) const
+ { return this->m_int > mi.m_int; }
+
+ int get_int() const
+ { return m_int; }
+
+ friend bool operator==(const movable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const movable_int &r)
+ { return l == r.get_int(); }
+
+ private:
+ int m_int;
+};
+
+template<class E, class T>
+std::basic_ostream<E, T> & operator<<
+ (std::basic_ostream<E, T> & os, movable_int const & p)
+
+{
+ os << p.get_int();
+ return os;
+}
+
+
+template<>
+struct is_copyable<movable_int>
+{
+ static const bool value = false;
+};
+
+class movable_and_copyable_int
+{
+ BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
+
+ public:
+ movable_and_copyable_int()
+ : m_int(0)
+ {}
+
+ explicit movable_and_copyable_int(int a)
+ : m_int(a)
+ {}
+
+ movable_and_copyable_int(const movable_and_copyable_int& mmi)
+ : m_int(mmi.m_int)
+ {}
+
+ movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi)
+ : m_int(mmi.m_int)
+ { mmi.m_int = 0; }
+
+ movable_and_copyable_int &operator= (BOOST_COPY_ASSIGN_REF(movable_and_copyable_int) mi)
+ { this->m_int = mi.m_int; return *this; }
+
+ movable_and_copyable_int & operator= (BOOST_RV_REF(movable_and_copyable_int) mmi)
+ { this->m_int = mmi.m_int; mmi.m_int = 0; return *this; }
+
+ movable_and_copyable_int & operator= (int i)
+ { this->m_int = i; return *this; }
+
+ bool operator ==(const movable_and_copyable_int &mi) const
+ { return this->m_int == mi.m_int; }
+
+ bool operator !=(const movable_and_copyable_int &mi) const
+ { return this->m_int != mi.m_int; }
+
+ bool operator <(const movable_and_copyable_int &mi) const
+ { return this->m_int < mi.m_int; }
+
+ bool operator <=(const movable_and_copyable_int &mi) const
+ { return this->m_int <= mi.m_int; }
+
+ bool operator >=(const movable_and_copyable_int &mi) const
+ { return this->m_int >= mi.m_int; }
+
+ bool operator >(const movable_and_copyable_int &mi) const
+ { return this->m_int > mi.m_int; }
+
+ int get_int() const
+ { return m_int; }
+
+ friend bool operator==(const movable_and_copyable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const movable_and_copyable_int &r)
+ { return l == r.get_int(); }
+
+ private:
+ int m_int;
+};
+
+template<class E, class T>
+std::basic_ostream<E, T> & operator<<
+ (std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
+
+{
+ os << p.get_int();
+ return os;
+}
+
+template<>
+struct is_copyable<movable_and_copyable_int>
+{
+ static const bool value = true;
+};
+
+class copyable_int
+{
+ public:
+ copyable_int()
+ : m_int(0)
+ {}
+
+ explicit copyable_int(int a)
+ : m_int(a)
+ {}
+
+ copyable_int(const copyable_int& mmi)
+ : m_int(mmi.m_int)
+ {}
+
+ copyable_int & operator= (int i)
+ { this->m_int = i; return *this; }
+
+ bool operator ==(const copyable_int &mi) const
+ { return this->m_int == mi.m_int; }
+
+ bool operator !=(const copyable_int &mi) const
+ { return this->m_int != mi.m_int; }
+
+ bool operator <(const copyable_int &mi) const
+ { return this->m_int < mi.m_int; }
+
+ bool operator <=(const copyable_int &mi) const
+ { return this->m_int <= mi.m_int; }
+
+ bool operator >=(const copyable_int &mi) const
+ { return this->m_int >= mi.m_int; }
+
+ bool operator >(const copyable_int &mi) const
+ { return this->m_int > mi.m_int; }
+
+ int get_int() const
+ { return m_int; }
+
+ friend bool operator==(const copyable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const copyable_int &r)
+ { return l == r.get_int(); }
+
+ private:
+ int m_int;
+};
+
+template<class E, class T>
+std::basic_ostream<E, T> & operator<<
+ (std::basic_ostream<E, T> & os, copyable_int const & p)
+
+{
+ os << p.get_int();
+ return os;
+}
+
+template<>
+struct is_copyable<copyable_int>
+{
+ static const bool value = true;
+};
+
+class non_copymovable_int
+{
+ non_copymovable_int(const non_copymovable_int& mmi);
+ non_copymovable_int & operator= (const non_copymovable_int &mi);
+
+ public:
+ non_copymovable_int()
+ : m_int(0)
+ {}
+
+ explicit non_copymovable_int(int a)
+ : m_int(a)
+ {}
+
+ bool operator ==(const non_copymovable_int &mi) const
+ { return this->m_int == mi.m_int; }
+
+ bool operator !=(const non_copymovable_int &mi) const
+ { return this->m_int != mi.m_int; }
+
+ bool operator <(const non_copymovable_int &mi) const
+ { return this->m_int < mi.m_int; }
+
+ bool operator <=(const non_copymovable_int &mi) const
+ { return this->m_int <= mi.m_int; }
+
+ bool operator >=(const non_copymovable_int &mi) const
+ { return this->m_int >= mi.m_int; }
+
+ bool operator >(const non_copymovable_int &mi) const
+ { return this->m_int > mi.m_int; }
+
+ int get_int() const
+ { return m_int; }
+
+ friend bool operator==(const non_copymovable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const non_copymovable_int &r)
+ { return l == r.get_int(); }
+
+ private:
+ int m_int;
+};
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_MOVABLE_INT_HEADER
diff --git a/src/boost/libs/interprocess/test/mutex_test.cpp b/src/boost/libs/interprocess/test/mutex_test.cpp
new file mode 100644
index 000000000..e3bd48207
--- /dev/null
+++ b/src/boost/libs/interprocess/test/mutex_test.cpp
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include "mutex_test_template.hpp"
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+#include <boost/interprocess/sync/windows/mutex.hpp>
+#include <boost/interprocess/sync/spin/mutex.hpp>
+#endif
+
+int main ()
+{
+ using namespace boost::interprocess;
+
+ #if defined(BOOST_INTERPROCESS_WINDOWS)
+ test::test_all_lock<ipcdetail::windows_mutex>();
+ test::test_all_mutex<ipcdetail::windows_mutex>();
+ test::test_all_lock<ipcdetail::spin_mutex>();
+ test::test_all_mutex<ipcdetail::spin_mutex>();
+ #endif
+
+ test::test_all_lock<interprocess_mutex>();
+ test::test_all_mutex<interprocess_mutex>();
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/mutex_test_template.hpp b/src/boost/libs/interprocess/test/mutex_test_template.hpp
new file mode 100644
index 000000000..f298fb8b4
--- /dev/null
+++ b/src/boost/libs/interprocess/test/mutex_test_template.hpp
@@ -0,0 +1,394 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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. William E. Kempf 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_TEST_MUTEX_TEST_TEMPLATE_HEADER
+#define BOOST_INTERPROCESS_TEST_MUTEX_TEST_TEMPLATE_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include "boost_interprocess_check.hpp"
+#include "util.hpp"
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <iostream>
+
+namespace boost { namespace interprocess { namespace test {
+
+template <typename M>
+struct test_lock
+{
+ typedef M mutex_type;
+ typedef boost::interprocess::scoped_lock<mutex_type> lock_type;
+
+
+ void operator()()
+ {
+ mutex_type interprocess_mutex;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(interprocess_mutex, boost::interprocess::defer_lock);
+ BOOST_INTERPROCESS_CHECK(!lock);
+ }
+ lock_type lock(interprocess_mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+
+ // Test the lock and unlock methods.
+ lock.unlock();
+ BOOST_INTERPROCESS_CHECK(!lock);
+ lock.lock();
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ }
+};
+
+template <typename M>
+struct test_trylock
+{
+ typedef M mutex_type;
+ typedef boost::interprocess::scoped_lock<mutex_type> try_to_lock_type;
+
+ void operator()()
+ {
+ mutex_type interprocess_mutex;
+
+ // Test the lock's constructors.
+ {
+ try_to_lock_type lock(interprocess_mutex, boost::interprocess::try_to_lock);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ }
+ {
+ try_to_lock_type lock(interprocess_mutex, boost::interprocess::defer_lock);
+ BOOST_INTERPROCESS_CHECK(!lock);
+ }
+ try_to_lock_type lock(interprocess_mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+
+ // Test the lock, unlock and trylock methods.
+ lock.unlock();
+ BOOST_INTERPROCESS_CHECK(!lock);
+ lock.lock();
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_INTERPROCESS_CHECK(!lock);
+ BOOST_INTERPROCESS_CHECK(lock.try_lock());
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ }
+};
+
+template <typename M>
+struct test_timedlock
+{
+ typedef M mutex_type;
+ typedef boost::interprocess::scoped_lock<mutex_type> timed_lock_type;
+
+ void operator()()
+ {
+ mutex_type interprocess_mutex;
+
+ // Test the lock's constructors.
+ {
+ // Construct and initialize an ptime for a fast time out.
+ boost::posix_time::ptime pt = delay(1*BaseSeconds, 0);
+
+ timed_lock_type lock(interprocess_mutex, pt);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ }
+ {
+ timed_lock_type lock(interprocess_mutex, boost::interprocess::defer_lock);
+ BOOST_INTERPROCESS_CHECK(!lock);
+ }
+ timed_lock_type lock(interprocess_mutex);
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+
+ // Test the lock, unlock and timedlock methods.
+ lock.unlock();
+ BOOST_INTERPROCESS_CHECK(!lock);
+ lock.lock();
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_INTERPROCESS_CHECK(!lock);
+ boost::posix_time::ptime pt = delay(3*BaseSeconds, 0);
+ BOOST_INTERPROCESS_CHECK(lock.timed_lock(pt));
+ BOOST_INTERPROCESS_CHECK(lock ? true : false);
+ }
+};
+
+template <typename M>
+struct test_recursive_lock
+{
+ typedef M mutex_type;
+ typedef boost::interprocess::scoped_lock<mutex_type> lock_type;
+
+ void operator()()
+ {
+ mutex_type mx;
+ {
+ lock_type lock1(mx);
+ lock_type lock2(mx);
+ }
+ {
+ lock_type lock1(mx, defer_lock);
+ lock_type lock2(mx, defer_lock);
+ }
+ {
+ lock_type lock1(mx, try_to_lock);
+ lock_type lock2(mx, try_to_lock);
+ }
+ {
+ //This should always lock
+ boost::posix_time::ptime pt = delay(2*BaseSeconds);
+ lock_type lock1(mx, pt);
+ lock_type lock2(mx, pt);
+ }
+ }
+};
+
+// plain_exclusive exercises the "infinite" lock for each
+// read_write_mutex type.
+
+template<typename M>
+void lock_and_sleep(void *arg, M &sm)
+{
+ data<M> *pdata = static_cast<data<M>*>(arg);
+ boost::interprocess::scoped_lock<M> l(sm);
+ if(pdata->m_secs){
+ boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs));
+ }
+ else{
+ boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
+ }
+
+ ++shared_val;
+ pdata->m_value = shared_val;
+}
+
+template<typename M>
+void lock_and_catch_errors(void *arg, M &sm)
+{
+ data<M> *pdata = static_cast<data<M>*>(arg);
+ try
+ {
+ boost::interprocess::scoped_lock<M> l(sm);
+ if(pdata->m_secs){
+ boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs));
+ }
+ else{
+ boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
+ }
+ ++shared_val;
+ pdata->m_value = shared_val;
+ }
+ catch(interprocess_exception const & e)
+ {
+ pdata->m_error = e.get_error_code();
+ }
+}
+
+template<typename M>
+void try_lock_and_sleep(void *arg, M &sm)
+{
+ data<M> *pdata = static_cast<data<M>*>(arg);
+ boost::interprocess::scoped_lock<M> l(sm, boost::interprocess::defer_lock);
+ if (l.try_lock()){
+ boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
+ ++shared_val;
+ pdata->m_value = shared_val;
+ }
+}
+
+template<typename M>
+void timed_lock_and_sleep(void *arg, M &sm)
+{
+ data<M> *pdata = static_cast<data<M>*>(arg);
+ boost::posix_time::ptime pt(delay(pdata->m_secs));
+ boost::interprocess::scoped_lock<M>
+ l (sm, boost::interprocess::defer_lock);
+ if (l.timed_lock(pt)){
+ boost::interprocess::ipcdetail::thread_sleep((1000*2*BaseSeconds));
+ ++shared_val;
+ pdata->m_value = shared_val;
+ }
+}
+
+template<typename M>
+void test_mutex_lock()
+{
+ shared_val = 0;
+
+ M mtx;
+
+ data<M> d1(1);
+ data<M> d2(2);
+
+ // Locker one launches, holds the lock for 2*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm1;
+ boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&lock_and_sleep, &d1, mtx));
+
+ //Wait 1*BaseSeconds
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+
+ // Locker two launches, but it won't hold the lock for 2*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm2;
+ boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&lock_and_sleep, &d2, mtx));
+
+ //Wait completion
+
+ boost::interprocess::ipcdetail::thread_join(tm1);
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+ boost::interprocess::ipcdetail::thread_join(tm2);
+
+ BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
+ BOOST_INTERPROCESS_CHECK(d2.m_value == 2);
+}
+
+template<typename M>
+void test_mutex_lock_timeout()
+{
+ shared_val = 0;
+
+ M mtx;
+
+ int wait_time_s = BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS / 1000;
+ if (wait_time_s == 0 )
+ wait_time_s = 1;
+
+ data<M> d1(1, wait_time_s * 3);
+ data<M> d2(2, wait_time_s * 2);
+
+ // Locker one launches, and holds the lock for wait_time_s * 2 seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm1;
+ boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&lock_and_sleep, &d1, mtx));
+
+ //Wait 1*BaseSeconds
+ boost::interprocess::ipcdetail::thread_sleep((1000*wait_time_s));
+
+ // Locker two launches, and attempts to hold the lock for wait_time_s * 2 seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm2;
+ boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&lock_and_catch_errors, &d2, mtx));
+
+ //Wait completion
+ boost::interprocess::ipcdetail::thread_join(tm1);
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+ boost::interprocess::ipcdetail::thread_join(tm2);
+
+ BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
+ BOOST_INTERPROCESS_CHECK(d2.m_value == -1);
+ BOOST_INTERPROCESS_CHECK(d1.m_error == no_error);
+ BOOST_INTERPROCESS_CHECK(d2.m_error == boost::interprocess::timeout_when_locking_error);
+}
+
+template<typename M>
+void test_mutex_try_lock()
+{
+ shared_val = 0;
+
+ M mtx;
+
+ data<M> d1(1);
+ data<M> d2(2);
+
+ // Locker one launches, holds the lock for 2*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm1;
+ boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&try_lock_and_sleep, &d1, mtx));
+
+ //Wait 1*BaseSeconds
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+
+ // Locker two launches, but it should fail acquiring the lock
+ boost::interprocess::ipcdetail::OS_thread_t tm2;
+ boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&try_lock_and_sleep, &d2, mtx));
+
+ //Wait completion
+ boost::interprocess::ipcdetail::thread_join(tm1);
+ boost::interprocess::ipcdetail::thread_join(tm2);
+
+ //Only the first should succeed locking
+ BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
+ BOOST_INTERPROCESS_CHECK(d2.m_value == -1);
+}
+
+template<typename M>
+void test_mutex_timed_lock()
+
+{
+ shared_val = 0;
+
+ M mtx, m2;
+
+ data<M> d1(1, 2*BaseSeconds);
+ data<M> d2(2, 2*BaseSeconds);
+
+ // Locker one launches, holds the lock for 2*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm1;
+ boost::interprocess::ipcdetail::thread_launch(tm1, thread_adapter<M>(&timed_lock_and_sleep, &d1, mtx));
+
+ //Wait 1*BaseSeconds
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+
+ // Locker two launches, holds the lock for 2*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tm2;
+ boost::interprocess::ipcdetail::thread_launch(tm2, thread_adapter<M>(&timed_lock_and_sleep, &d2, mtx));
+
+ //Wait completion
+ boost::interprocess::ipcdetail::thread_join(tm1);
+ boost::interprocess::ipcdetail::thread_join(tm2);
+
+ //Both should succeed locking
+ BOOST_INTERPROCESS_CHECK(d1.m_value == 1);
+ BOOST_INTERPROCESS_CHECK(d2.m_value == 2);
+}
+
+template <typename M>
+inline void test_all_lock()
+{
+ //Now generic interprocess_mutex tests
+ std::cout << "test_lock<" << typeid(M).name() << ">" << std::endl;
+ test_lock<M>()();
+ std::cout << "test_trylock<" << typeid(M).name() << ">" << std::endl;
+ test_trylock<M>()();
+ std::cout << "test_timedlock<" << typeid(M).name() << ">" << std::endl;
+ test_timedlock<M>()();
+}
+
+template <typename M>
+inline void test_all_recursive_lock()
+{
+ //Now generic interprocess_mutex tests
+ std::cout << "test_recursive_lock<" << typeid(M).name() << ">" << std::endl;
+ test_recursive_lock<M>()();
+}
+
+template<typename M>
+void test_all_mutex()
+{
+ std::cout << "test_mutex_lock<" << typeid(M).name() << ">" << std::endl;
+ test_mutex_lock<M>();
+ std::cout << "test_mutex_try_lock<" << typeid(M).name() << ">" << std::endl;
+ test_mutex_try_lock<M>();
+ std::cout << "test_mutex_timed_lock<" << typeid(M).name() << ">" << std::endl;
+ test_mutex_timed_lock<M>();
+}
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_TEST_MUTEX_TEST_TEMPLATE_HEADER
diff --git a/src/boost/libs/interprocess/test/mutex_timeout_test.cpp b/src/boost/libs/interprocess/test/mutex_timeout_test.cpp
new file mode 100644
index 000000000..7dc4df522
--- /dev/null
+++ b/src/boost/libs/interprocess/test/mutex_timeout_test.cpp
@@ -0,0 +1,30 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// enable timeout feature
+#define BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
+#define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 1000
+
+#include <boost/assert.hpp>
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include "mutex_test_template.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+ test::test_mutex_lock_timeout<interprocess_mutex>();
+ test::test_mutex_lock_timeout<interprocess_recursive_mutex>();
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_allocation_test_template.hpp b/src/boost/libs/interprocess/test/named_allocation_test_template.hpp
new file mode 100644
index 000000000..ca796349f
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_allocation_test_template.hpp
@@ -0,0 +1,495 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
+#define BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+
+// interprocess
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/streams/bufferstream.hpp>
+#include <boost/interprocess/sync/mutex_family.hpp>
+// container
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/minimal_char_traits_header.hpp> //char_traits
+// std
+#include <cstdio>
+#include <iostream>
+#include <new>
+#include <set>
+#include <vector>
+
+// local
+#include "get_process_id_name.hpp"
+
+namespace boost { namespace interprocess { namespace test {
+
+namespace {
+ const wchar_t *get_prefix(wchar_t)
+ { return L"prefix_name_"; }
+
+ const char *get_prefix(char)
+ { return "prefix_name_"; }
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the same order
+template<class ManagedMemory>
+bool test_names_and_types(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+ typedef std::char_traits<char_type> char_traits_type;
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ for(int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+
+ if(!ptr)
+ break;
+
+ std::size_t namelen = char_traits_type::length(m.get_instance_name(ptr));
+ if(namelen != char_traits_type::length(name)){
+ return 1;
+ }
+
+ if(char_traits_type::compare(m.get_instance_name(ptr), name, namelen) != 0){
+ return 1;
+ }
+
+ if(m.template find<char>(name).first == 0)
+ return false;
+
+ if(m.get_instance_type(ptr) != named_type)
+ return false;
+
+ buffers.push_back(ptr);
+ }
+
+ if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
+ return false;
+
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ m.destroy_ptr(buffers[j]);
+ }
+
+ if(m.get_num_named_objects() != 0 || !m.check_sanity())
+ return false;
+ m.shrink_to_fit_indexes();
+ if(!m.all_memory_deallocated())
+ return false;
+ return true;
+}
+
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the same order
+template<class ManagedMemory>
+bool test_named_iterators(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+ typedef std::basic_string<char_type> string_type;
+ std::set<string_type> names;
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ string_type aux_str;
+
+ for(int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+ if(!ptr)
+ break;
+ aux_str = name;
+ names.insert(aux_str);
+ buffers.push_back(ptr);
+ }
+
+ if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
+ return false;
+
+ typedef typename ManagedMemory::const_named_iterator const_named_iterator;
+ const_named_iterator named_beg = m.named_begin();
+ const_named_iterator named_end = m.named_end();
+
+ if((std::size_t)boost::container::iterator_distance(named_beg, named_end) != (std::size_t)buffers.size()){
+ return 1;
+ }
+
+ for(; named_beg != named_end; ++named_beg){
+ const char_type *name_str = named_beg->name();
+ aux_str = name_str;
+ if(names.find(aux_str) == names.end()){
+ return 1;
+ }
+
+ if(aux_str.size() != named_beg->name_length()){
+ return 1;
+ }
+
+ const void *found_value = m.template find<char>(name_str).first;
+
+ if(found_value == 0)
+ return false;
+ if(found_value != named_beg->value())
+ return false;
+ }
+
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ m.destroy_ptr(buffers[j]);
+ }
+
+ if(m.get_num_named_objects() != 0 || !m.check_sanity())
+ return false;
+ m.shrink_to_fit_indexes();
+ if(!m.all_memory_deallocated())
+ return false;
+ return true;
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the same order
+template<class ManagedMemory>
+bool test_shrink_to_fit(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ std::size_t free_memory_before = m.get_free_memory();
+
+ for(int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+
+ if(!ptr)
+ break;
+ buffers.push_back(ptr);
+ }
+
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ m.destroy_ptr(buffers[j]);
+ }
+
+ std::size_t free_memory_after = m.get_free_memory();
+
+ if(free_memory_before != free_memory_after){
+ m.shrink_to_fit_indexes();
+ if(free_memory_before != free_memory_after)
+ return false;
+ }
+ return true;
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the same order
+template<class ManagedMemory>
+bool test_direct_named_allocation_destruction(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ for(int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+ if(!ptr)
+ break;
+ if(m.template find<char>(name).first == 0)
+ return false;
+ buffers.push_back(ptr);
+ }
+
+ if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
+ return false;
+
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ m.destroy_ptr(buffers[j]);
+ }
+
+ if(m.get_num_named_objects() != 0 || !m.check_sanity())
+ return false;
+ m.shrink_to_fit_indexes();
+ if(!m.all_memory_deallocated())
+ return false;
+ return true;
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the inverse order
+template<class ManagedMemory>
+bool test_named_allocation_inverse_destruction(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ for(int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+ if(!ptr)
+ break;
+ buffers.push_back(ptr);
+ }
+
+ if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
+ return false;
+
+ for(int j = (int)buffers.size()
+ ;j--
+ ;){
+ m.destroy_ptr(buffers[j]);
+ }
+
+ if(m.get_num_named_objects() != 0 || !m.check_sanity())
+ return false;
+ m.shrink_to_fit_indexes();
+ if(!m.all_memory_deallocated())
+ return false;
+ return true;
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all following a pattern
+template<class ManagedMemory>
+bool test_named_allocation_mixed_destruction(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ for(int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+ if(!ptr)
+ break;
+ buffers.push_back(ptr);
+ }
+
+ if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
+ return false;
+
+ for(int j = 0, max = (int)buffers.size()
+ ;j < max
+ ;++j){
+ int pos = (j%4)*((int)buffers.size())/4;
+ m.destroy_ptr(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
+ }
+
+ if(m.get_num_named_objects() != 0 || !m.check_sanity())
+ return false;
+ m.shrink_to_fit_indexes();
+ if(!m.all_memory_deallocated())
+ return false;
+ return true;
+}
+
+//This test allocates until there is no more memory
+//and after that deallocates all in the same order
+template<class ManagedMemory>
+bool test_inverse_named_allocation_destruction(ManagedMemory &m)
+{
+ typedef typename ManagedMemory::char_type char_type;
+
+ std::vector<char*> buffers;
+ const int BufferLen = 100;
+ char_type name[BufferLen];
+
+ basic_bufferstream<char_type> formatter(name, BufferLen);
+
+ for(unsigned int i = 0; true; ++i){
+ formatter.seekp(0);
+ formatter << get_prefix(char_type()) << i << std::ends;
+ char *ptr = m.template construct<char>(name, std::nothrow)(i);
+ if(!ptr)
+ break;
+ buffers.push_back(ptr);
+ }
+
+ if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
+ return false;
+
+ for(unsigned int j = 0, max = (unsigned int)buffers.size()
+ ;j < max
+ ;++j){
+ m.destroy_ptr(buffers[j]);
+ }
+
+ if(m.get_num_named_objects() != 0 || !m.check_sanity())
+ return false;
+ m.shrink_to_fit_indexes();
+ if(!m.all_memory_deallocated())
+ return false;
+ return true;
+}
+
+///This function calls all tests
+template<class ManagedMemory>
+bool test_all_named_allocation(ManagedMemory &m)
+{
+ std::cout << "Starting test_names_and_types. Class: "
+ << typeid(m).name() << std::endl;
+
+ if(!test_names_and_types(m)){
+ std::cout << "test_names_and_types failed. Class: "
+ << typeid(m).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_direct_named_allocation_destruction. Class: "
+ << typeid(m).name() << std::endl;
+
+ if(!test_direct_named_allocation_destruction(m)){
+ std::cout << "test_direct_named_allocation_destruction failed. Class: "
+ << typeid(m).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_named_allocation_inverse_destruction. Class: "
+ << typeid(m).name() << std::endl;
+
+ if(!test_named_allocation_inverse_destruction(m)){
+ std::cout << "test_named_allocation_inverse_destruction failed. Class: "
+ << typeid(m).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_named_allocation_mixed_destruction. Class: "
+ << typeid(m).name() << std::endl;
+
+ if(!test_named_allocation_mixed_destruction(m)){
+ std::cout << "test_named_allocation_mixed_destruction failed. Class: "
+ << typeid(m).name() << std::endl;
+ return false;
+ }
+
+ std::cout << "Starting test_inverse_named_allocation_destruction. Class: "
+ << typeid(m).name() << std::endl;
+
+ if(!test_inverse_named_allocation_destruction(m)){
+ std::cout << "test_inverse_named_allocation_destruction failed. Class: "
+ << typeid(m).name() << std::endl;
+ return false;
+ }
+
+ if(!test_named_iterators(m)){
+ std::cout << "test_named_iterators failed. Class: "
+ << typeid(m).name() << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+//This function calls all tests
+template<template <class IndexConfig> class Index>
+bool test_named_allocation()
+{
+ using namespace boost::interprocess;
+
+ const int memsize = 163840;
+ const char *const shMemName = test::get_process_id_name();
+ try
+ {
+ //A shared memory with rbtree best fit algorithm
+ typedef basic_managed_shared_memory
+ <char
+ ,rbtree_best_fit<mutex_family>
+ ,Index
+ > my_managed_shared_memory;
+
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ my_managed_shared_memory segment(create_only, shMemName, memsize);
+
+ //Now take the segment manager and launch memory test
+ if(!test::test_all_named_allocation(*segment.get_segment_manager())){
+ return false;
+ }
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+
+ //Now test it with wchar_t
+ try
+ {
+ //A shared memory with simple sequential fit algorithm
+ typedef basic_managed_shared_memory
+ <wchar_t
+ ,rbtree_best_fit<mutex_family>
+ ,Index
+ > my_managed_shared_memory;
+
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ my_managed_shared_memory segment(create_only, shMemName, memsize);
+
+ //Now take the segment manager and launch memory test
+ if(!test::test_all_named_allocation(*segment.get_segment_manager())){
+ return false;
+ }
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+
+ return true;
+}
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
diff --git a/src/boost/libs/interprocess/test/named_condition_any_test.cpp b/src/boost/libs/interprocess/test/named_condition_any_test.cpp
new file mode 100644
index 000000000..500cb185a
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_condition_any_test.cpp
@@ -0,0 +1,189 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+#include <boost/interprocess/sync/named_mutex.hpp>
+#include <boost/interprocess/sync/named_condition_any.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
+#include "condition_test_template.hpp"
+#include "named_creation_template.hpp"
+#include <string>
+#include <sstream>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+struct condition_deleter
+{
+ std::string name;
+
+ ~condition_deleter()
+ {
+ if(name.empty())
+ named_condition_any::remove(test::add_to_process_id_name("named_condition_any"));
+ else
+ named_condition_any::remove(name.c_str());
+ }
+};
+
+inline std::string num_to_string(int n)
+{ std::stringstream s; s << n; return s.str(); }
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class named_condition_any_test_wrapper
+ : public condition_deleter, public named_condition_any
+{
+ public:
+
+ named_condition_any_test_wrapper()
+ : named_condition_any(open_or_create,
+ (test::add_to_process_id_name("test_cond") + num_to_string(count)).c_str())
+ {
+ condition_deleter::name += test::add_to_process_id_name("test_cond");
+ condition_deleter::name += num_to_string(count);
+ ++count;
+ }
+
+ ~named_condition_any_test_wrapper()
+ { --count; }
+
+
+ template <typename L>
+ void wait(L& lock)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ named_condition_any::wait(internal_lock);
+ }
+
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ named_condition_any::wait(internal_lock, pred);
+ }
+
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return named_condition_any::timed_wait(internal_lock, abs_time);
+ }
+
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return named_condition_any::timed_wait(internal_lock, abs_time, pred);
+ }
+
+ static int count;
+};
+
+int named_condition_any_test_wrapper::count = 0;
+
+//This wrapper is necessary to have a common constructor
+//in generic named_creation_template functions
+class named_condition_any_creation_test_wrapper
+ : public condition_deleter, public named_condition_any
+{
+ public:
+ named_condition_any_creation_test_wrapper(create_only_t)
+ : named_condition_any(create_only, test::add_to_process_id_name("named_condition_any"))
+ { ++count_; }
+
+ named_condition_any_creation_test_wrapper(open_only_t)
+ : named_condition_any(open_only, test::add_to_process_id_name("named_condition_any"))
+ { ++count_; }
+
+ named_condition_any_creation_test_wrapper(open_or_create_t)
+ : named_condition_any(open_or_create, test::add_to_process_id_name("named_condition_any"))
+ { ++count_; }
+
+ ~named_condition_any_creation_test_wrapper() {
+ if(--count_){
+ ipcdetail::interprocess_tester::
+ dont_close_on_destruction(static_cast<named_condition_any&>(*this));
+ }
+ }
+ static int count_;
+};
+
+int named_condition_any_creation_test_wrapper::count_ = 0;
+
+struct mutex_deleter
+{
+ std::string name;
+
+ ~mutex_deleter()
+ {
+ if(name.empty())
+ named_mutex::remove(test::add_to_process_id_name("named_mutex"));
+ else
+ named_mutex::remove(name.c_str());
+ }
+};
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class named_mutex_test_wrapper
+ : public mutex_deleter, public named_mutex
+{
+ public:
+ named_mutex_test_wrapper()
+ : named_mutex(open_or_create,
+ (test::add_to_process_id_name("test_mutex") + num_to_string(count)).c_str())
+ {
+ mutex_deleter::name += test::add_to_process_id_name("test_mutex");
+ mutex_deleter::name += num_to_string(count);
+ ++count;
+ }
+
+ typedef named_mutex internal_mutex_type;
+
+ internal_mutex_type &internal_mutex()
+ { return *this; }
+
+ ~named_mutex_test_wrapper()
+ { --count; }
+
+ static int count;
+};
+
+int named_mutex_test_wrapper::count = 0;
+
+int main ()
+{
+ try{
+ //Remove previous mutexes and conditions
+ named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
+ named_condition_any::remove(test::add_to_process_id_name("test_cond0"));
+ named_condition_any::remove(test::add_to_process_id_name("test_cond1"));
+ named_condition_any::remove(test::add_to_process_id_name("named_condition_any"));
+ named_mutex::remove(test::add_to_process_id_name("named_mutex"));
+
+ test::test_named_creation<named_condition_any_creation_test_wrapper>();
+ test::do_test_condition<named_condition_any_test_wrapper
+ ,named_mutex_test_wrapper>();
+ }
+ catch(std::exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
+ named_condition_any::remove(test::add_to_process_id_name("test_cond0"));
+ named_condition_any::remove(test::add_to_process_id_name("test_cond1"));
+ named_condition_any::remove(test::add_to_process_id_name("named_condition_any"));
+ named_mutex::remove(test::add_to_process_id_name("named_mutex"));
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_condition_test.cpp b/src/boost/libs/interprocess/test/named_condition_test.cpp
new file mode 100644
index 000000000..6aa9c7812
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_condition_test.cpp
@@ -0,0 +1,189 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+#include <boost/interprocess/sync/named_mutex.hpp>
+#include <boost/interprocess/sync/named_condition.hpp>
+#include <boost/interprocess/sync/detail/locks.hpp>
+#include "condition_test_template.hpp"
+#include "named_creation_template.hpp"
+#include <string>
+#include <sstream>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+struct condition_deleter
+{
+ std::string name;
+
+ ~condition_deleter()
+ {
+ if(name.empty())
+ named_condition::remove(test::add_to_process_id_name("named_condition"));
+ else
+ named_condition::remove(name.c_str());
+ }
+};
+
+inline std::string num_to_string(int n)
+{ std::stringstream s; s << n; return s.str(); }
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class named_condition_test_wrapper
+ : public condition_deleter, public named_condition
+{
+ public:
+
+ named_condition_test_wrapper()
+ : named_condition(open_or_create,
+ (test::add_to_process_id_name("test_cond") + num_to_string(count)).c_str())
+ {
+ condition_deleter::name += test::add_to_process_id_name("test_cond");
+ condition_deleter::name += num_to_string(count);
+ ++count;
+ }
+
+ ~named_condition_test_wrapper()
+ { --count; }
+
+
+ template <typename L>
+ void wait(L& lock)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ named_condition::wait(internal_lock);
+ }
+
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ named_condition::wait(internal_lock, pred);
+ }
+
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return named_condition::timed_wait(internal_lock, abs_time);
+ }
+
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+ {
+ ipcdetail::internal_mutex_lock<L> internal_lock(lock);
+ return named_condition::timed_wait(internal_lock, abs_time, pred);
+ }
+
+ static int count;
+};
+
+int named_condition_test_wrapper::count = 0;
+
+//This wrapper is necessary to have a common constructor
+//in generic named_creation_template functions
+class named_condition_creation_test_wrapper
+ : public condition_deleter, public named_condition
+{
+ public:
+ named_condition_creation_test_wrapper(create_only_t)
+ : named_condition(create_only, test::add_to_process_id_name("named_condition"))
+ { ++count_; }
+
+ named_condition_creation_test_wrapper(open_only_t)
+ : named_condition(open_only, test::add_to_process_id_name("named_condition"))
+ { ++count_; }
+
+ named_condition_creation_test_wrapper(open_or_create_t)
+ : named_condition(open_or_create, test::add_to_process_id_name("named_condition"))
+ { ++count_; }
+
+ ~named_condition_creation_test_wrapper() {
+ if(--count_){
+ ipcdetail::interprocess_tester::
+ dont_close_on_destruction(static_cast<named_condition&>(*this));
+ }
+ }
+ static int count_;
+};
+
+int named_condition_creation_test_wrapper::count_ = 0;
+
+struct mutex_deleter
+{
+ std::string name;
+
+ ~mutex_deleter()
+ {
+ if(name.empty())
+ named_mutex::remove(test::add_to_process_id_name("named_mutex"));
+ else
+ named_mutex::remove(name.c_str());
+ }
+};
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class named_mutex_test_wrapper
+ : public mutex_deleter, public named_mutex
+{
+ public:
+ named_mutex_test_wrapper()
+ : named_mutex(open_or_create,
+ (test::add_to_process_id_name("test_mutex") + num_to_string(count)).c_str())
+ {
+ mutex_deleter::name += test::add_to_process_id_name("test_mutex");
+ mutex_deleter::name += num_to_string(count);
+ ++count;
+ }
+
+ typedef named_mutex internal_mutex_type;
+
+ internal_mutex_type &internal_mutex()
+ { return *this; }
+
+ ~named_mutex_test_wrapper()
+ { --count; }
+
+ static int count;
+};
+
+int named_mutex_test_wrapper::count = 0;
+
+int main ()
+{
+ try{
+ //Remove previous mutexes and conditions
+ named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
+ named_condition::remove(test::add_to_process_id_name("test_cond0"));
+ named_condition::remove(test::add_to_process_id_name("test_cond1"));
+ named_condition::remove(test::add_to_process_id_name("named_condition"));
+ named_mutex::remove(test::add_to_process_id_name("named_mutex"));
+
+ test::test_named_creation<named_condition_creation_test_wrapper>();
+ test::do_test_condition<named_condition_test_wrapper
+ ,named_mutex_test_wrapper>();
+ }
+ catch(std::exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_mutex::remove(test::add_to_process_id_name("test_mutex0"));
+ named_condition::remove(test::add_to_process_id_name("test_cond0"));
+ named_condition::remove(test::add_to_process_id_name("test_cond1"));
+ named_condition::remove(test::add_to_process_id_name("named_condition"));
+ named_mutex::remove(test::add_to_process_id_name("named_mutex"));
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_construct_test.cpp b/src/boost/libs/interprocess/test/named_construct_test.cpp
new file mode 100644
index 000000000..834a993f5
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_construct_test.cpp
@@ -0,0 +1,196 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2012. 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>
+#include <boost/interprocess/managed_shared_memory.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp>
+
+typedef std::pair<double, int> simple_pair;
+
+using namespace boost::interprocess;
+
+struct array_pair : public simple_pair
+{
+ array_pair(double d, int i)
+ : simple_pair(d, i) {}
+};
+
+struct array_it_pair : public array_pair
+{
+ array_it_pair(double d, int i)
+ : array_pair(d, i) {}
+};
+
+struct named_name_generator
+{
+ static const bool searchable = true;
+
+ typedef simple_pair simple_type;
+ typedef array_pair array_type;
+ typedef array_it_pair array_it_type;
+ static const char *get_simple_name()
+ { return "MyType instance"; }
+ static const char *get_array_name()
+ { return "MyType array"; }
+ static const char *get_array_it_name()
+ { return "MyType array from it"; }
+};
+
+struct unique_name_generator
+{
+ static const bool searchable = true;
+
+ typedef simple_pair simple_type;
+ typedef array_pair array_type;
+ typedef array_it_pair array_it_type;
+ static const ipcdetail::unique_instance_t *get_simple_name()
+ { return 0; }
+ static const ipcdetail::unique_instance_t *get_array_name()
+ { return 0; }
+ static const ipcdetail::unique_instance_t *get_array_it_name()
+ { return 0; }
+};
+
+struct anonymous_name_generator
+{
+ static const bool searchable = false;
+
+ typedef simple_pair simple_type;
+ typedef array_pair array_type;
+ typedef array_it_pair array_it_type;
+ static const ipcdetail::anonymous_instance_t *get_simple_name()
+ { return 0; }
+ static const ipcdetail::anonymous_instance_t *get_array_name()
+ { return 0; }
+ static const ipcdetail::anonymous_instance_t *get_array_it_name()
+ { return 0; }
+};
+
+
+template<class NameGenerator>
+int construct_test()
+{
+ typedef typename NameGenerator::simple_type simple_type;
+ typedef typename NameGenerator::array_type array_type;
+ typedef typename NameGenerator::array_it_type array_it_type;
+
+ remove_shared_memory_on_destroy remover("MySharedMemory");
+ shared_memory_object::remove("MySharedMemory");
+ {
+ //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
+ managed_shared_memory segment
+ //create segment name segment size
+ (create_only, "MySharedMemory", 65536);
+
+ //Create an object of MyType initialized to {0.0, 0}
+ simple_type *s = segment.construct<simple_type>
+ (NameGenerator::get_simple_name())//name of the object
+ (1.0, 2); //ctor first argument
+ assert(s->first == 1.0 && s->second == 2);
+ if(!(s->first == 1.0 && s->second == 2))
+ return 1;
+
+ //Create an array of 10 elements of MyType initialized to {0.0, 0}
+ array_type *a = segment.construct<array_type>
+ (NameGenerator::get_array_name()) //name of the object
+ [10] //number of elements
+ (3.0, 4); //Same two ctor arguments for all objects
+ assert(a->first == 3.0 && a->second == 4);
+ if(!(a->first == 3.0 && a->second == 4))
+ return 1;
+
+ //Create an array of 3 elements of MyType initializing each one
+ //to a different value {0.0, 3}, {1.0, 4}, {2.0, 5}...
+ float float_initializer[3] = { 0.0, 1.0, 2.0 };
+ int int_initializer[3] = { 3, 4, 5 };
+
+ array_it_type *a_it = segment.construct_it<array_it_type>
+ (NameGenerator::get_array_it_name()) //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
+ {
+ const array_it_type *a_it_ptr = a_it;
+ for(unsigned int i = 0, max = 3; i != max; ++i, ++a_it_ptr){
+ assert(a_it_ptr->first == float_initializer[i]);
+ if(a_it_ptr->first != float_initializer[i]){
+ return 1;
+ }
+ assert(a_it_ptr->second == int_initializer[i]);
+ if(a_it_ptr->second != int_initializer[i]){
+ return 1;
+ }
+ }
+ }
+
+ if(NameGenerator::searchable){
+ {
+ std::pair<simple_type*, managed_shared_memory::size_type> res;
+ //Find the object
+ res = segment.find<simple_type> (NameGenerator::get_simple_name());
+ //Length should be 1
+ assert(res.second == 1);
+ if(res.second != 1)
+ return 1;
+ assert(res.first == s);
+ if(res.first != s)
+ return 1;
+ }
+ {
+ std::pair<array_type*, managed_shared_memory::size_type> res;
+
+ //Find the array
+ res = segment.find<array_type> (NameGenerator::get_array_name());
+ //Length should be 10
+ assert(res.second == 10);
+ if(res.second != 10)
+ return 1;
+ assert(res.first == a);
+ if(res.first != a)
+ return 1;
+ }
+ {
+ std::pair<array_it_type*, managed_shared_memory::size_type> res;
+ //Find the array constructed from iterators
+ res = segment.find<array_it_type> (NameGenerator::get_array_it_name());
+ //Length should be 3
+ assert(res.second == 3);
+ if(res.second != 3)
+ return 1;
+ assert(res.first == a_it);
+ if(res.first != a_it)
+ return 1;
+ }
+ }
+ //We're done, delete all the objects
+ segment.destroy_ptr<simple_type>(s);
+ segment.destroy_ptr<array_type>(a);
+ segment.destroy_ptr<array_it_type>(a_it);
+ }
+ return 0;
+}
+
+int main ()
+{
+ if(0 != construct_test<named_name_generator>())
+ return 1;
+ if(0 != construct_test<unique_name_generator>())
+ return 1;
+ if(0 != construct_test<anonymous_name_generator>())
+ return 1;
+ return 0;
+}
+
+//]
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_creation_template.hpp b/src/boost/libs/interprocess/test/named_creation_template.hpp
new file mode 100644
index 000000000..1e0029917
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_creation_template.hpp
@@ -0,0 +1,132 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_TEST_NAMED_RESOURCE_TEMPLATE_HEADER
+#define BOOST_INTERPROCESS_TEST_NAMED_RESOURCE_TEMPLATE_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include "boost_interprocess_check.hpp"
+#include "get_process_id_name.hpp"
+#include <iostream>
+#include <typeinfo>
+#include <boost/interprocess/creation_tags.hpp>
+
+namespace boost { namespace interprocess { namespace test {
+
+template <class NamedResource>
+inline void create_then_open_then_open_or_create()
+{
+ try{
+ //Create it and open it twice
+ NamedResource nresource1(create_only);
+ NamedResource nresource2(open_only);
+ NamedResource nresource3(open_or_create);
+ }
+ catch(...){
+ //This shouldn't throw so show the error
+ BOOST_INTERPROCESS_CHECK( false );
+ }
+}
+
+template <class NamedResource>
+inline void open_or_create_then_create()
+{
+ //Create it with open_or_create and try to create it twice
+ NamedResource nresource1(open_or_create);
+ try{
+ NamedResource nresource2(create_only);
+ }
+ catch(interprocess_exception &err){
+ BOOST_INTERPROCESS_CHECK(err.get_error_code() == already_exists_error);
+ }
+}
+
+template <class NamedResource>
+inline void dont_create_and_open()
+{
+ //Try to open it without creating
+ try{
+ NamedResource nresource1(open_only);
+ }
+ catch(interprocess_exception &err){
+ BOOST_INTERPROCESS_CHECK(err.get_error_code() == not_found_error);
+ return;
+ }
+ //The mutex should not exist
+ BOOST_INTERPROCESS_CHECK(false);
+}
+
+template <class NamedResource>
+inline void test_named_creation()
+{
+ std::cout << "create_then_open_then_open_or_create<"
+ << typeid(NamedResource).name() << ">" << std::endl;
+ create_then_open_then_open_or_create<NamedResource>();
+ std::cout << "open_or_create_then_create<"
+ << typeid(NamedResource).name() << ">" << std::endl;
+ open_or_create_then_create<NamedResource>();
+ std::cout << "dont_create_and_open<"
+ << typeid(NamedResource).name() << ">" << std::endl;
+ dont_create_and_open<NamedResource>();
+}
+
+template<class NamedSync>
+class named_sync_wrapper
+ : public NamedSync
+{
+ public:
+ named_sync_wrapper()
+ : NamedSync(open_or_create, test::get_process_id_ptr_name(this))
+ {}
+
+ ~named_sync_wrapper()
+ {
+ NamedSync::remove(test::get_process_id_ptr_name(this));
+ }
+};
+
+template<class NamedSync>
+struct named_sync_deleter
+{
+ ~named_sync_deleter()
+ { NamedSync::remove(test::get_process_id_name()); }
+};
+
+
+//This wrapper is necessary to have a common constructor
+//in generic named_creation_template functions
+template<class NamedSync>
+class named_sync_creation_test_wrapper
+ : public test::named_sync_deleter<NamedSync>, public NamedSync
+{
+ public:
+ named_sync_creation_test_wrapper(create_only_t)
+ : NamedSync(create_only, test::get_process_id_name())
+ {}
+
+ named_sync_creation_test_wrapper(open_only_t)
+ : NamedSync(open_only, test::get_process_id_name())
+ {}
+
+ named_sync_creation_test_wrapper(open_or_create_t)
+ : NamedSync(open_or_create, test::get_process_id_name())
+ {}
+
+ ~named_sync_creation_test_wrapper()
+ {}
+};
+
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_TEST_NAMED_RESOURCE_TEMPLATE_HEADER
diff --git a/src/boost/libs/interprocess/test/named_mutex_test.cpp b/src/boost/libs/interprocess/test/named_mutex_test.cpp
new file mode 100644
index 000000000..11c7f1c45
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_mutex_test.cpp
@@ -0,0 +1,38 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/sync/named_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include "mutex_test_template.hpp"
+#include "named_creation_template.hpp"
+#include <string>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ named_mutex::remove(test::get_process_id_name());
+ test::test_named_creation< test::named_sync_creation_test_wrapper<named_mutex> >();
+ test::test_all_lock< test::named_sync_wrapper<named_mutex> >();
+ test::test_all_mutex<test::named_sync_wrapper<named_mutex> >();
+ }
+ catch(std::exception &ex){
+ named_mutex::remove(test::get_process_id_name());
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_mutex::remove(test::get_process_id_name());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_recursive_mutex_test.cpp b/src/boost/libs/interprocess/test/named_recursive_mutex_test.cpp
new file mode 100644
index 000000000..376c1e3cd
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_recursive_mutex_test.cpp
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/sync/named_recursive_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include "mutex_test_template.hpp"
+#include "named_creation_template.hpp"
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ named_recursive_mutex::remove(test::get_process_id_name());
+ test::test_named_creation< test::named_sync_creation_test_wrapper<named_recursive_mutex> >();
+ test::test_all_lock< test::named_sync_wrapper<named_recursive_mutex> >();
+ test::test_all_mutex<test::named_sync_wrapper<named_recursive_mutex> >();
+ test::test_all_recursive_lock<test::named_sync_wrapper<named_recursive_mutex> >();
+ }
+ catch(std::exception &ex){
+ named_recursive_mutex::remove(test::get_process_id_name());
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_recursive_mutex::remove(test::get_process_id_name());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
+
diff --git a/src/boost/libs/interprocess/test/named_semaphore_test.cpp b/src/boost/libs/interprocess/test/named_semaphore_test.cpp
new file mode 100644
index 000000000..57087977d
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_semaphore_test.cpp
@@ -0,0 +1,123 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/sync/named_semaphore.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include "named_creation_template.hpp"
+#include "mutex_test_template.hpp"
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+static const std::size_t RecSemCount = 100;
+static const char * SemName = test::get_process_id_name();
+
+//This wrapper is necessary to plug this class
+//in lock tests
+class lock_test_wrapper
+ : public named_semaphore
+{
+ public:
+
+ lock_test_wrapper(create_only_t, const char *name, unsigned int count = 1)
+ : named_semaphore(create_only, name, count)
+ {}
+
+ lock_test_wrapper(open_only_t, const char *name)
+ : named_semaphore(open_only, name)
+ {}
+
+ lock_test_wrapper(open_or_create_t, const char *name, unsigned int count = 1)
+ : named_semaphore(open_or_create, name, count)
+ {}
+
+ ~lock_test_wrapper()
+ {}
+
+ void lock()
+ { this->wait(); }
+
+ bool try_lock()
+ { return this->try_wait(); }
+
+ bool timed_lock(const boost::posix_time::ptime &pt)
+ { return this->timed_wait(pt); }
+
+ void unlock()
+ { this->post(); }
+};
+
+//This wrapper is necessary to plug this class
+//in recursive tests
+class recursive_test_wrapper
+ : public lock_test_wrapper
+{
+ public:
+ recursive_test_wrapper(create_only_t, const char *name)
+ : lock_test_wrapper(create_only, name, RecSemCount)
+ {}
+
+ recursive_test_wrapper(open_only_t, const char *name)
+ : lock_test_wrapper(open_only, name)
+ {}
+
+ recursive_test_wrapper(open_or_create_t, const char *name)
+ : lock_test_wrapper(open_or_create, name, RecSemCount)
+ {}
+};
+
+bool test_named_semaphore_specific()
+{
+ //Test persistance
+ {
+ named_semaphore sem(create_only, SemName, 3);
+ }
+ {
+ named_semaphore sem(open_only, SemName);
+ BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCESS_CHECK(sem.try_wait() == false);
+ sem.post();
+ }
+ {
+ named_semaphore sem(open_only, SemName);
+ BOOST_INTERPROCESS_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCESS_CHECK(sem.try_wait() == false);
+ }
+
+ named_semaphore::remove(SemName);
+ return true;
+}
+
+int main ()
+{
+ try{
+ named_semaphore::remove(SemName);
+ test::test_named_creation< test::named_sync_creation_test_wrapper<lock_test_wrapper> >();
+ test::test_all_lock< test::named_sync_wrapper<lock_test_wrapper> >();
+ test::test_all_mutex<test::named_sync_wrapper<lock_test_wrapper> >();
+ test::test_all_recursive_lock<test::named_sync_wrapper<recursive_test_wrapper> >();
+ test_named_semaphore_specific();
+ }
+ catch(std::exception &ex){
+ named_semaphore::remove(SemName);
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_semaphore::remove(SemName);
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_sharable_mutex_test.cpp b/src/boost/libs/interprocess/test/named_sharable_mutex_test.cpp
new file mode 100644
index 000000000..9721ab07e
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_sharable_mutex_test.cpp
@@ -0,0 +1,103 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 "mutex_test_template.hpp"
+#include "sharable_mutex_test_template.hpp"
+#include "named_creation_template.hpp"
+#include <boost/interprocess/sync/named_sharable_mutex.hpp>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+struct mutex_deleter
+{
+ ~mutex_deleter()
+ { named_sharable_mutex::remove(test::get_process_id_name()); }
+};
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class named_sharable_mutex_lock_test_wrapper
+ : public named_sharable_mutex
+{
+ public:
+ named_sharable_mutex_lock_test_wrapper()
+ : named_sharable_mutex(open_or_create, test::get_process_id_name())
+ { ++count_; }
+
+ ~named_sharable_mutex_lock_test_wrapper()
+ {
+ if(--count_){
+ ipcdetail::interprocess_tester::
+ dont_close_on_destruction(static_cast<named_sharable_mutex&>(*this));
+ }
+ }
+
+ static int count_;
+};
+
+int named_sharable_mutex_lock_test_wrapper::count_ = 0;
+
+
+//This wrapper is necessary to have a common constructor
+//in generic named_creation_template functions
+class named_sharable_mutex_creation_test_wrapper
+ : public mutex_deleter, public named_sharable_mutex
+{
+ public:
+ named_sharable_mutex_creation_test_wrapper
+ (create_only_t)
+ : named_sharable_mutex(create_only, test::get_process_id_name())
+ { ++count_; }
+
+ named_sharable_mutex_creation_test_wrapper
+ (open_only_t)
+ : named_sharable_mutex(open_only, test::get_process_id_name())
+ { ++count_; }
+
+ named_sharable_mutex_creation_test_wrapper
+ (open_or_create_t)
+ : named_sharable_mutex(open_or_create, test::get_process_id_name())
+ { ++count_; }
+
+ ~named_sharable_mutex_creation_test_wrapper()
+ {
+ if(--count_){
+ ipcdetail::interprocess_tester::
+ dont_close_on_destruction(static_cast<named_sharable_mutex&>(*this));
+ }
+ }
+
+ static int count_;
+};
+
+int named_sharable_mutex_creation_test_wrapper::count_ = 0;
+
+int main ()
+{
+ try{
+ named_sharable_mutex::remove(test::get_process_id_name());
+ test::test_named_creation< test::named_sync_creation_test_wrapper<named_sharable_mutex> >();
+ test::test_all_lock< test::named_sync_wrapper<named_sharable_mutex> >();
+ test::test_all_mutex<test::named_sync_wrapper<named_sharable_mutex> >();
+ test::test_all_sharable_mutex<test::named_sync_wrapper<named_sharable_mutex> >();
+ }
+ catch(std::exception &ex){
+ named_sharable_mutex::remove(test::get_process_id_name());
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_sharable_mutex::remove(test::get_process_id_name());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/named_upgradable_mutex_test.cpp b/src/boost/libs/interprocess/test/named_upgradable_mutex_test.cpp
new file mode 100644
index 000000000..c0d2bcd00
--- /dev/null
+++ b/src/boost/libs/interprocess/test/named_upgradable_mutex_test.cpp
@@ -0,0 +1,103 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 "mutex_test_template.hpp"
+#include "sharable_mutex_test_template.hpp"
+#include "named_creation_template.hpp"
+#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+struct mutex_deleter
+{
+ ~mutex_deleter()
+ { named_upgradable_mutex::remove(test::get_process_id_name()); }
+};
+
+//This wrapper is necessary to have a default constructor
+//in generic mutex_test_template functions
+class named_upgradable_mutex_lock_test_wrapper
+ : public named_upgradable_mutex
+{
+ public:
+ named_upgradable_mutex_lock_test_wrapper()
+ : named_upgradable_mutex(open_or_create, test::get_process_id_name())
+ { ++count_; }
+
+ ~named_upgradable_mutex_lock_test_wrapper()
+ {
+ if(--count_){
+ ipcdetail::interprocess_tester::
+ dont_close_on_destruction(static_cast<named_upgradable_mutex&>(*this));
+ }
+ }
+
+ static int count_;
+};
+
+int named_upgradable_mutex_lock_test_wrapper::count_ = 0;
+
+
+//This wrapper is necessary to have a common constructor
+//in generic named_creation_template functions
+class named_upgradable_mutex_creation_test_wrapper
+ : public mutex_deleter, public named_upgradable_mutex
+{
+ public:
+ named_upgradable_mutex_creation_test_wrapper
+ (create_only_t)
+ : named_upgradable_mutex(create_only, test::get_process_id_name())
+ { ++count_; }
+
+ named_upgradable_mutex_creation_test_wrapper
+ (open_only_t)
+ : named_upgradable_mutex(open_only, test::get_process_id_name())
+ { ++count_; }
+
+ named_upgradable_mutex_creation_test_wrapper
+ (open_or_create_t)
+ : named_upgradable_mutex(open_or_create, test::get_process_id_name())
+ { ++count_; }
+
+ ~named_upgradable_mutex_creation_test_wrapper()
+ {
+ if(--count_){
+ ipcdetail::interprocess_tester::
+ dont_close_on_destruction(static_cast<named_upgradable_mutex&>(*this));
+ }
+ }
+
+ static int count_;
+};
+
+int named_upgradable_mutex_creation_test_wrapper::count_ = 0;
+
+int main ()
+{
+ try{
+ named_upgradable_mutex::remove(test::get_process_id_name());
+ test::test_named_creation< test::named_sync_creation_test_wrapper<named_upgradable_mutex> >();
+ test::test_all_lock< test::named_sync_wrapper<named_upgradable_mutex> >();
+ test::test_all_mutex<test::named_sync_wrapper<named_upgradable_mutex> >();
+ test::test_all_sharable_mutex<test::named_sync_wrapper<named_upgradable_mutex> >();
+ }
+ catch(std::exception &ex){
+ named_upgradable_mutex::remove(test::get_process_id_name());
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ named_upgradable_mutex::remove(test::get_process_id_name());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/node_allocator_test.cpp b/src/boost/libs/interprocess/test/node_allocator_test.cpp
new file mode 100644
index 000000000..4ff7097e7
--- /dev/null
+++ b/src/boost/libs/interprocess/test/node_allocator_test.cpp
@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/node_allocator.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "list_test.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//We will work with wide characters for shared memory objects
+//Alias an integer node allocator type
+typedef node_allocator
+ <int, managed_shared_memory::segment_manager> shmem_node_allocator_t;
+typedef ipcdetail::node_allocator_v1
+ <int, managed_shared_memory::segment_manager> shmem_node_allocator_v1_t;
+
+namespace boost {
+namespace interprocess {
+
+//Explicit instantiations to catch compilation errors
+template class node_allocator<int, managed_shared_memory::segment_manager>;
+template class node_allocator<void, managed_shared_memory::segment_manager>;
+
+namespace ipcdetail {
+
+template class ipcdetail::node_allocator_v1<int, managed_shared_memory::segment_manager>;
+template class ipcdetail::node_allocator_v1<void, managed_shared_memory::segment_manager>;
+
+}}}
+
+//Alias list types
+typedef list<int, shmem_node_allocator_t> MyShmList;
+typedef list<int, shmem_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, shmem_node_allocator_t> MyShmVector;
+typedef vector<int, shmem_node_allocator_v1_t> MyShmVectorV1;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyShmList, true>())
+ return 1;
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/node_pool_test.cpp b/src/boost/libs/interprocess/test/node_pool_test.cpp
new file mode 100644
index 000000000..149bd7f65
--- /dev/null
+++ b/src/boost/libs/interprocess/test/node_pool_test.cpp
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2012. 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 "node_pool_test.hpp"
+#include <boost/interprocess/allocators/detail/node_pool.hpp>
+
+using namespace boost::interprocess;
+
+typedef managed_shared_memory::segment_manager segment_manager_t;
+
+int main ()
+{
+ typedef ipcdetail::private_node_pool
+ <segment_manager_t, 4, 64> node_pool_t;
+
+ if(!test::test_all_node_pool<node_pool_t>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/node_pool_test.hpp b/src/boost/libs/interprocess/test/node_pool_test.hpp
new file mode 100644
index 000000000..52fc8ffa8
--- /dev/null
+++ b/src/boost/libs/interprocess/test/node_pool_test.hpp
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <vector>
+#include <cstddef>
+#include <string>
+#include "get_process_id_name.hpp"
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+template <class NodePool>
+struct test_node_pool
+{
+ static bool allocate_then_deallocate(NodePool &pool);
+ static bool deallocate_free_blocks(NodePool &pool);
+};
+
+template <class NodePool>
+bool test_node_pool<NodePool>::allocate_then_deallocate(NodePool &pool)
+{
+ const typename NodePool::size_type num_alloc = 1 + 3*pool.get_real_num_node();
+
+ std::vector<void*> nodes;
+
+ //Precondition, the pool must be empty
+ if(0 != pool.num_free_nodes()){
+ return false;
+ }
+
+ //First allocate nodes
+ for(std::size_t i = 0; i < num_alloc; ++i){
+ nodes.push_back(pool.allocate_node());
+ }
+
+ //Check that the free count is correct
+ if((pool.get_real_num_node() - 1) != pool.num_free_nodes()){
+ return false;
+ }
+
+ //Now deallocate all and check again
+ for(std::size_t i = 0; i < num_alloc; ++i){
+ pool.deallocate_node(nodes[i]);
+ }
+
+ //Check that the free count is correct
+ if(4*pool.get_real_num_node() != pool.num_free_nodes()){
+ return false;
+ }
+
+ pool.deallocate_free_blocks();
+
+ if(0 != pool.num_free_nodes()){
+ return false;
+ }
+
+ return true;
+}
+
+template <class NodePool>
+bool test_node_pool<NodePool>::deallocate_free_blocks(NodePool &pool)
+{
+ const std::size_t max_blocks = 10;
+ const std::size_t max_nodes = max_blocks*pool.get_real_num_node();
+ const std::size_t nodes_per_block = pool.get_real_num_node();
+
+ std::vector<void*> nodes;
+
+ //Precondition, the pool must be empty
+ if(0 != pool.num_free_nodes()){
+ return false;
+ }
+
+ //First allocate nodes
+ for(std::size_t i = 0; i < max_nodes; ++i){
+ nodes.push_back(pool.allocate_node());
+ }
+
+ //Check that the free count is correct
+ if(0 != pool.num_free_nodes()){
+ return false;
+ }
+
+ //Now deallocate one of each block per iteration
+ for(std::size_t node_i = 0; node_i < nodes_per_block; ++node_i){
+ //Deallocate a node per block
+ for(std::size_t i = 0; i < max_blocks; ++i){
+ pool.deallocate_node(nodes[i*nodes_per_block + node_i]);
+ }
+
+ //Check that the free count is correct
+ if(max_blocks*(node_i+1) != pool.num_free_nodes()){
+ return false;
+ }
+
+ //Now try to deallocate free blocks
+ pool.deallocate_free_blocks();
+
+ //Until we don't deallocate the last node of every block
+ //no node should be deallocated
+ if(node_i != (nodes_per_block - 1)){
+ if(max_blocks*(node_i+1) != pool.num_free_nodes()){
+ return false;
+ }
+ }
+ else{
+ //If this is the last iteration, all the memory should
+ //have been deallocated.
+ if(0 != pool.num_free_nodes()){
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+template<class node_pool_t>
+bool test_all_node_pool()
+{
+ using namespace boost::interprocess;
+ typedef managed_shared_memory::segment_manager segment_manager;
+
+ typedef boost::interprocess::test::test_node_pool<node_pool_t> test_node_pool_t;
+ shared_memory_object::remove(test::get_process_id_name());
+ {
+ managed_shared_memory shm(create_only, test::get_process_id_name(), 4*1024*sizeof(segment_manager::void_pointer));
+
+ typedef deleter<node_pool_t, segment_manager> deleter_t;
+ typedef unique_ptr<node_pool_t, deleter_t> unique_ptr_t;
+
+ //Delete the pool when the tests end
+ unique_ptr_t p
+ (shm.construct<node_pool_t>(anonymous_instance)(shm.get_segment_manager())
+ ,deleter_t(shm.get_segment_manager()));
+
+ //Now call each test
+ if(!test_node_pool_t::allocate_then_deallocate(*p))
+ return false;
+ if(!test_node_pool_t::deallocate_free_blocks(*p))
+ return false;
+ }
+ shared_memory_object::remove(test::get_process_id_name());
+ return true;
+}
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/null_index_test.cpp b/src/boost/libs/interprocess/test/null_index_test.cpp
new file mode 100644
index 000000000..e0f23407e
--- /dev/null
+++ b/src/boost/libs/interprocess/test/null_index_test.cpp
@@ -0,0 +1,51 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2012. 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/indexes/null_index.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
+#include <cstddef>
+#include <cassert>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+typedef basic_managed_shared_memory
+ <char, simple_seq_fit<mutex_family>, null_index>
+my_shared_objects_t;
+
+int main ()
+{
+ //Create shared memory
+ shared_memory_object::remove(test::get_process_id_name());
+ {
+ my_shared_objects_t segment
+ (create_only,
+ test::get_process_id_name(), //segment name
+ 65536); //segment size in bytes
+
+ //Allocate a portion of the segment
+ void * shptr = segment.allocate(1024/*bytes to allocate*/);
+ my_shared_objects_t::handle_t handle = segment.get_handle_from_address(shptr);
+ if(!segment.belongs_to_segment(shptr)){
+ return 1;
+ }
+ if(shptr != segment.get_address_from_handle(handle)){
+ return 1;
+ }
+
+ segment.deallocate(shptr);
+ }
+ shared_memory_object::remove(test::get_process_id_name());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/offset_ptr_test.cpp b/src/boost/libs/interprocess/test/offset_ptr_test.cpp
new file mode 100644
index 000000000..bece39b01
--- /dev/null
+++ b/src/boost/libs/interprocess/test/offset_ptr_test.cpp
@@ -0,0 +1,352 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2012. 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/offset_ptr.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+using namespace boost::interprocess;
+
+class Base
+{};
+
+class Derived
+ : public Base
+{};
+
+class VirtualDerived
+ : public virtual Base
+{};
+
+void test_types_and_conversions()
+{
+ typedef offset_ptr<int> pint_t;
+ typedef offset_ptr<const int> pcint_t;
+ typedef offset_ptr<volatile int> pvint_t;
+ typedef offset_ptr<const volatile int> pcvint_t;
+
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::element_type, int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::element_type, const int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::element_type, volatile int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::element_type, const volatile int>::value));
+
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::value_type, int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::value_type, int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::value_type, int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::value_type, int>::value));
+ int dummy_int = 9;
+
+ { pint_t pint(&dummy_int);
+ pcint_t pcint(pint);
+ BOOST_TEST(pcint.get() == &dummy_int);
+ }
+ { pint_t pint(&dummy_int);
+ pvint_t pvint(pint);
+ BOOST_TEST(pvint.get() == &dummy_int);
+ }
+ { pint_t pint(&dummy_int);
+ pcvint_t pcvint(pint);
+ BOOST_TEST(pcvint.get() == &dummy_int);
+ }
+ { pcint_t pcint(&dummy_int);
+ pcvint_t pcvint(pcint);
+ BOOST_TEST(pcvint.get() == &dummy_int);
+ }
+ { pvint_t pvint(&dummy_int);
+ pcvint_t pcvint(pvint);
+ BOOST_TEST(pcvint.get() == &dummy_int);
+ }
+
+ pint_t pint(0);
+ pcint_t pcint(0);
+ pvint_t pvint(0);
+ pcvint_t pcvint(0);
+
+ pint = &dummy_int;
+ pcint = &dummy_int;
+ pvint = &dummy_int;
+ pcvint = &dummy_int;
+
+ { pcint = pint;
+ BOOST_TEST(pcint.get() == &dummy_int);
+ }
+ { pvint = pint;
+ BOOST_TEST(pvint.get() == &dummy_int);
+ }
+ { pcvint = pint;
+ BOOST_TEST(pcvint.get() == &dummy_int);
+ }
+ { pcvint = pcint;
+ BOOST_TEST(pcvint.get() == &dummy_int);
+ }
+ { pcvint = pvint;
+ BOOST_TEST(pcvint.get() == &dummy_int);
+ }
+
+ BOOST_TEST(pint);
+
+ pint = 0;
+ BOOST_TEST(!pint);
+
+ BOOST_TEST(pint == 0);
+
+ BOOST_TEST(0 == pint);
+
+ pint = &dummy_int;
+ BOOST_TEST(0 != pint);
+
+ pcint = &dummy_int;
+
+ BOOST_TEST( (pcint - pint) == 0);
+ BOOST_TEST( (pint - pcint) == 0);
+}
+
+template<class BasePtr, class DerivedPtr>
+void test_base_derived_impl()
+{
+ typename DerivedPtr::element_type d;
+ DerivedPtr pderi(&d);
+
+ BasePtr pbase(pderi);
+ pbase = pderi;
+ BOOST_TEST(pbase == pderi);
+ BOOST_TEST(!(pbase != pderi));
+ BOOST_TEST((pbase - pderi) == 0);
+ BOOST_TEST(!(pbase < pderi));
+ BOOST_TEST(!(pbase > pderi));
+ BOOST_TEST(pbase <= pderi);
+ BOOST_TEST((pbase >= pderi));
+}
+
+void test_base_derived()
+{
+ typedef offset_ptr<Base> pbase_t;
+ typedef offset_ptr<const Base> pcbas_t;
+ typedef offset_ptr<Derived> pderi_t;
+ typedef offset_ptr<VirtualDerived> pvder_t;
+
+ test_base_derived_impl<pbase_t, pderi_t>();
+ test_base_derived_impl<pbase_t, pvder_t>();
+ test_base_derived_impl<pcbas_t, pderi_t>();
+ test_base_derived_impl<pcbas_t, pvder_t>();
+}
+
+void test_arithmetic()
+{
+ typedef offset_ptr<int> pint_t;
+ const int NumValues = 5;
+ int values[NumValues];
+
+ //Initialize p
+ pint_t p = values;
+ BOOST_TEST(p.get() == values);
+
+ //Initialize p + NumValues
+ pint_t pe = &values[NumValues];
+ BOOST_TEST(pe != p);
+ BOOST_TEST(pe.get() == &values[NumValues]);
+
+ //ptr - ptr
+ BOOST_TEST((pe - p) == NumValues);
+
+ //ptr - integer
+ BOOST_TEST((pe - NumValues) == p);
+
+ //ptr + integer
+ BOOST_TEST((p + NumValues) == pe);
+
+ //integer + ptr
+ BOOST_TEST((NumValues + p) == pe);
+
+ //indexing
+ BOOST_TEST(pint_t(&p[NumValues]) == pe);
+ BOOST_TEST(pint_t(&pe[-NumValues]) == p);
+
+ //ptr -= integer
+ pint_t p0 = pe;
+ p0-= NumValues;
+ BOOST_TEST(p == p0);
+
+ //ptr += integer
+ pint_t penew = p0;
+ penew += NumValues;
+ BOOST_TEST(penew == pe);
+
+ //++ptr
+ penew = p0;
+ for(int j = 0; j != NumValues; ++j, ++penew);
+ BOOST_TEST(penew == pe);
+
+ //--ptr
+ p0 = pe;
+ for(int j = 0; j != NumValues; ++j, --p0);
+ BOOST_TEST(p == p0);
+
+ //ptr++
+ penew = p0;
+ for(int j = 0; j != NumValues; ++j){
+ pint_t p_new_copy = penew;
+ BOOST_TEST(p_new_copy == penew++);
+ }
+ //ptr--
+ p0 = pe;
+ for(int j = 0; j != NumValues; ++j){
+ pint_t p0_copy = p0;
+ BOOST_TEST(p0_copy == p0--);
+ }
+}
+
+void test_comparison()
+{
+ typedef offset_ptr<int> pint_t;
+ const int NumValues = 5;
+ int values[NumValues];
+
+ //Initialize p
+ pint_t p = values;
+ BOOST_TEST(p.get() == values);
+
+ //Initialize p + NumValues
+ pint_t pe = &values[NumValues];
+ BOOST_TEST(pe != p);
+
+ BOOST_TEST(pe.get() == &values[NumValues]);
+
+ //operators
+ BOOST_TEST(p != pe);
+ BOOST_TEST(p == p);
+ BOOST_TEST((p < pe));
+ BOOST_TEST((p <= pe));
+ BOOST_TEST((pe > p));
+ BOOST_TEST((pe >= p));
+}
+
+bool test_pointer_traits()
+{
+ typedef offset_ptr<int> OInt;
+ typedef boost::intrusive::pointer_traits< OInt > PTOInt;
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::element_type, int>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::pointer, OInt >::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::difference_type, OInt::difference_type >::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::rebind_pointer<double>::type, offset_ptr<double> >::value));
+ int dummy;
+ OInt oi(&dummy);
+ if(boost::intrusive::pointer_traits<OInt>::pointer_to(dummy) != oi){
+ return false;
+ }
+ return true;
+}
+
+struct node
+{
+ offset_ptr<node> next;
+};
+
+void test_pointer_plus_bits()
+{
+ BOOST_STATIC_ASSERT((boost::intrusive::max_pointer_plus_bits< offset_ptr<void>, boost::move_detail::alignment_of<node>::value >::value >= 1U));
+ typedef boost::intrusive::pointer_plus_bits< offset_ptr<node>, 1u > ptr_plus_bits;
+
+ node n, n2;
+ offset_ptr<node> pnode(&n);
+
+ BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
+ BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
+ ptr_plus_bits::set_bits(pnode, 1u);
+ BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
+ BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
+
+ ptr_plus_bits::set_pointer(pnode, &n2);
+ BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
+ BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
+ ptr_plus_bits::set_bits(pnode, 0u);
+ BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
+ BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
+
+ ptr_plus_bits::set_pointer(pnode, offset_ptr<node>());
+ BOOST_TEST(ptr_plus_bits::get_pointer(pnode) ==0);
+ BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
+ ptr_plus_bits::set_bits(pnode, 1u);
+ BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
+ BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == 0);
+}
+
+int main()
+{
+ test_types_and_conversions();
+ test_base_derived();
+ test_arithmetic();
+ test_comparison();
+ test_pointer_traits();
+ test_pointer_plus_bits();
+ return ::boost::report_errors();
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+/*
+//Offset ptr benchmark
+#include <vector>
+#include <iostream>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/timer.hpp>
+#include <cstddef>
+
+template<class InIt,
+ class Ty> inline
+ Ty accumulate2(InIt First, InIt Last, Ty Val)
+ { // return sum of Val and all in [First, Last)
+ for (; First != Last; ++First) //First = First + 1)
+ Val = Val + *First;
+ return (Val);
+ }
+
+template <typename Vector>
+void time_test(const Vector& vec, std::size_t iterations, const char* label) {
+ // assert(!vec.empty())
+ boost::timer t;
+ typename Vector::const_iterator first = vec.begin();
+ typename Vector::value_type result(0);
+ while (iterations != 0) {
+ result = accumulate2(first, first + vec.size(), result);
+ --iterations;
+ }
+ std::cout << label << t.elapsed() << " " << result << std::endl;
+}
+
+int main()
+{
+ using namespace boost::interprocess;
+ typedef allocator<double, managed_shared_memory::segment_manager> alloc_t;
+
+ std::size_t n = 0x1 << 26;
+ std::size_t file_size = n * sizeof(double) + 1000000;
+
+ {
+ shared_memory_object::remove("MyMappedFile");
+ managed_shared_memory segment(open_or_create, "MyMappedFile", file_size);
+ shared_memory_object::remove("MyMappedFile");
+ alloc_t alloc_inst(segment.get_segment_manager());
+ vector<double, alloc_t> v0(n, double(42.42), alloc_inst);
+ time_test(v0, 10, "iterator shared: ");
+ }
+ {
+ std::vector<double> v1(n, double(42.42));
+ time_test(v1, 10, "iterator non-shared: ");
+ }
+ return 0;
+}
+
+*/
diff --git a/src/boost/libs/interprocess/test/print_container.hpp b/src/boost/libs/interprocess/test/print_container.hpp
new file mode 100644
index 000000000..b045bb42e
--- /dev/null
+++ b/src/boost/libs/interprocess/test/print_container.hpp
@@ -0,0 +1,56 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_TEST_PRINTCONTAINER_HPP
+#define BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <iostream>
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template<class Container>
+void PrintContents(const Container &cont, const char *contName)
+{
+ std::cout<< "Printing contents of " << contName << std::endl;
+ typename Container::iterator b(cont.begin()), e(cont.end());
+ for(; b != e; ++b){
+ std::cout << *b << " ";
+ }
+ std::cout<< std::endl << std::endl;
+}
+
+//Function to dump data
+template<class MyShmCont, class MyStdCont>
+void PrintContainers(MyShmCont *shmcont, MyStdCont *stdcont)
+{
+ typename MyShmCont::iterator itshm = shmcont->begin(), itshmend = shmcont->end();
+ typename MyStdCont::iterator itstd = stdcont->begin(), itstdend = stdcont->end();
+
+ std::cout << "MyShmCont" << std::endl;
+ for(; itshm != itshmend; ++itshm){
+ std::cout << *itshm << std::endl;
+ }
+ std::cout << "MyStdCont" << std::endl;
+
+ for(; itstd != itstdend; ++itstd){
+ std::cout << *itstd << std::endl;
+ }
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP
diff --git a/src/boost/libs/interprocess/test/private_adaptive_pool_test.cpp b/src/boost/libs/interprocess/test/private_adaptive_pool_test.cpp
new file mode 100644
index 000000000..55868a0db
--- /dev/null
+++ b/src/boost/libs/interprocess/test/private_adaptive_pool_test.cpp
@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/private_adaptive_pool.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "list_test.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//We will work with wide characters for shared memory objects
+//Alias a private adaptive pool that allocates ints
+typedef private_adaptive_pool
+ <int, managed_shared_memory::segment_manager> priv_node_allocator_t;
+typedef ipcdetail::private_adaptive_pool_v1
+ <int, managed_shared_memory::segment_manager> priv_node_allocator_v1_t;
+
+namespace boost {
+namespace interprocess {
+
+//Explicit instantiations to catch compilation errors
+template class private_adaptive_pool<int, managed_shared_memory::segment_manager>;
+template class private_adaptive_pool<void, managed_shared_memory::segment_manager>;
+
+namespace ipcdetail {
+
+template class ipcdetail::private_adaptive_pool_v1<int, managed_shared_memory::segment_manager>;
+template class ipcdetail::private_adaptive_pool_v1<void, managed_shared_memory::segment_manager>;
+
+}}}
+
+//Alias list types
+typedef list<int, priv_node_allocator_t> MyShmList;
+typedef list<int, priv_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, priv_node_allocator_t> MyShmVector;
+typedef vector<int, priv_node_allocator_v1_t> MyShmVectorV1;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyShmList, true>(false))
+ return 1;
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>(false))
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/private_node_allocator_test.cpp b/src/boost/libs/interprocess/test/private_node_allocator_test.cpp
new file mode 100644
index 000000000..4690f83fa
--- /dev/null
+++ b/src/boost/libs/interprocess/test/private_node_allocator_test.cpp
@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/allocators/private_node_allocator.hpp>
+#include "print_container.hpp"
+#include "dummy_test_allocator.hpp"
+#include "movable_int.hpp"
+#include "list_test.hpp"
+#include "vector_test.hpp"
+
+using namespace boost::interprocess;
+
+//We will work with wide characters for shared memory objects
+//Alias an integer node allocator type
+typedef private_node_allocator
+ <int, managed_shared_memory::segment_manager> priv_node_allocator_t;
+typedef ipcdetail::private_node_allocator_v1
+ <int, managed_shared_memory::segment_manager> priv_node_allocator_v1_t;
+
+namespace boost {
+namespace interprocess {
+
+//Explicit instantiations to catch compilation errors
+template class private_node_allocator<int, managed_shared_memory::segment_manager>;
+template class private_node_allocator<void, managed_shared_memory::segment_manager>;
+
+namespace ipcdetail {
+
+template class ipcdetail::private_node_allocator_v1<int, managed_shared_memory::segment_manager>;
+template class ipcdetail::private_node_allocator_v1<void, managed_shared_memory::segment_manager>;
+
+}}}
+
+//Alias list types
+typedef list<int, priv_node_allocator_t> MyShmList;
+typedef list<int, priv_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, priv_node_allocator_t> MyShmVector;
+typedef vector<int, priv_node_allocator_v1_t> MyShmVectorV1;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyShmList, true>(false))
+ return 1;
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>(false))
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/recursive_mutex_test.cpp b/src/boost/libs/interprocess/test/recursive_mutex_test.cpp
new file mode 100644
index 000000000..8bec0344e
--- /dev/null
+++ b/src/boost/libs/interprocess/test/recursive_mutex_test.cpp
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+#include <boost/interprocess/sync/windows/recursive_mutex.hpp>
+#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
+#endif
+#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include "mutex_test_template.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+ #if defined(BOOST_INTERPROCESS_WINDOWS)
+ //
+ test::test_all_lock<ipcdetail::windows_recursive_mutex>();
+ test::test_all_mutex<ipcdetail::windows_recursive_mutex>();
+ test::test_all_recursive_lock<ipcdetail::windows_recursive_mutex>();
+ //
+ test::test_all_lock<ipcdetail::spin_recursive_mutex>();
+ test::test_all_mutex<ipcdetail::spin_recursive_mutex>();
+ test::test_all_recursive_lock<ipcdetail::spin_recursive_mutex>();
+ #endif
+ //
+ test::test_all_lock<interprocess_recursive_mutex>();
+ test::test_all_mutex<interprocess_recursive_mutex>();
+ test::test_all_recursive_lock<interprocess_recursive_mutex>();
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/robust_emulation_test.cpp b/src/boost/libs/interprocess/test/robust_emulation_test.cpp
new file mode 100644
index 000000000..98a64e0fd
--- /dev/null
+++ b/src/boost/libs/interprocess/test/robust_emulation_test.cpp
@@ -0,0 +1,22 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2012. 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 "robust_mutex_test.hpp"
+#include <boost/interprocess/detail/robust_emulation.hpp>
+#include <boost/interprocess/sync/spin/mutex.hpp>
+
+int main(int argc, char *argv[])
+{
+ using namespace boost::interprocess;
+ return test::robust_mutex_test
+ < ipcdetail::robust_spin_mutex<ipcdetail::spin_mutex> >(argc, argv);
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/robust_mutex_test.hpp b/src/boost/libs/interprocess/test/robust_mutex_test.hpp
new file mode 100644
index 000000000..09688c3d0
--- /dev/null
+++ b/src/boost/libs/interprocess/test/robust_mutex_test.hpp
@@ -0,0 +1,208 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2012. 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_TEST_ROBUST_MUTEX_TEST_HEADER
+#define BOOST_INTERPROCESS_TEST_ROBUST_MUTEX_TEST_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <iostream>
+#include <cstdlib> //std::system
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/sync/spin/wait.hpp>
+#include "get_process_id_name.hpp"
+#include "mutex_test_template.hpp"
+#include <iostream>
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template<class RobustMutex>
+int robust_mutex_test(int argc, char *argv[])
+{
+ try{
+ if(argc == 1){ //Parent process
+ //First usual mutex tests
+ {
+ // test_all_lock<RobustMutex>();
+// test_all_mutex<true, RobustMutex>();
+ }
+ std::cout << "robust mutex recovery test" << std::endl;
+
+ //Remove shared memory on construction and destruction
+ class shm_remove
+ {
+ public:
+ shm_remove(){ shared_memory_object::remove
+ (::boost::interprocess::test::get_process_id_name()); }
+ ~shm_remove(){ shared_memory_object::remove
+ (::boost::interprocess::test::get_process_id_name()); }
+ } remover;
+ (void)remover;
+
+ //Construct managed shared memory
+ managed_shared_memory segment(create_only, get_process_id_name(), 65536);
+
+ //Create two robust mutexes
+ RobustMutex *instance = segment.construct<RobustMutex>
+ ("robust mutex")[2]();
+
+ //Create a flag to notify that both mutexes are
+ //locked and the owner is going to die soon.
+ bool *go_ahead = segment.construct<bool> ("go ahead")(false);
+
+ //Launch child process
+ std::string s(argv[0]); s += " child ";
+ s += get_process_id_name();
+ std::cout << "... launching child" << std::endl;
+ if(0 != std::system(s.c_str()))
+ return 1;
+
+ //Wait until child locks the mutexes and dies
+ spin_wait swait;
+ while(!*go_ahead){
+ swait.yield();
+ }
+
+ std::cout << "... recovering mutex[0]" << std::endl;
+ //First try to recover lock[0], put into consistent
+ //state and relock it again
+ {
+ //Done, now try to lock it to see if robust
+ //mutex recovery works
+ instance[0].lock();
+ if(!instance[0].previous_owner_dead())
+ return 1;
+ instance[0].consistent();
+ instance[0].unlock();
+ //Since it's consistent, locking is possible again
+ instance[0].lock();
+ instance[0].unlock();
+ }
+ //Now with lock[1], but dont' put it in consistent state
+ //so the mutex is no longer usable
+ std::cout << "... recovering mutex[1]" << std::endl;
+ {
+ //Done, now try to lock it to see if robust
+ //mutex recovery works
+ instance[1].lock();
+ if(!instance[1].previous_owner_dead())
+ return 1;
+ //Unlock a recovered mutex without putting it into
+ //into consistent state marks mutex as unusable.
+ instance[1].unlock();
+ //Since it's NOT consistent, locking is NOT possible again
+ bool exception_thrown = false;
+ try{
+ instance[1].lock();
+ }
+ catch(interprocess_exception &){
+ exception_thrown = true;
+ }
+ if(!exception_thrown){
+ return 1;
+ }
+ }
+ //Now with lock[2], this was locked by child but not
+ //unlocked
+ std::cout << "... recovering mutex[2]" << std::endl;
+ {
+ //Done, now try to lock it to see if robust
+ //mutex recovery works
+ instance[2].lock();
+ if(!instance[2].previous_owner_dead())
+ return 1;
+ //Unlock a recovered mutex without putting it into
+ //into consistent state marks mutex as unusable.
+ instance[2].unlock();
+ //Since it's NOT consistent, locking is NOT possible again
+ bool exception_thrown = false;
+ try{
+ instance[2].lock();
+ }
+ catch(interprocess_exception &){
+ exception_thrown = true;
+ }
+ if(!exception_thrown){
+ return 1;
+ }
+ }
+ }
+ else{
+ //Open managed shared memory
+ managed_shared_memory segment(open_only, argv[2]);
+ //Find mutexes
+ RobustMutex *instance = segment.find<RobustMutex>("robust mutex").first;
+ assert(instance);
+ if(std::string(argv[1]) == std::string("child")){
+ std::cout << "launched child" << std::endl;
+ //Find flag
+ bool *go_ahead = segment.find<bool>("go ahead").first;
+ assert(go_ahead);
+ //Lock, flag and die
+ bool try_lock_res = instance[0].try_lock() && instance[1].try_lock();
+ assert(try_lock_res);
+ if(!try_lock_res)
+ return 1;
+
+ bool *go_ahead2 = segment.construct<bool>("go ahead2")(false);
+ assert(go_ahead2);
+ //Launch grandchild
+ std::string s(argv[0]); s += " grandchild ";
+ s += argv[2];
+ std::cout << "... launching grandchild" << std::endl;
+ if(0 != std::system(s.c_str())){
+ std::cout << "launched terminated with error" << std::endl;
+ return 1;
+ }
+
+ //Wait until child locks the 2nd mutex and dies
+ spin_wait swait;
+ while(!*go_ahead2){
+ swait.yield();
+ }
+
+ //Done, now try to lock number 3 to see if robust
+ //mutex recovery works
+ instance[2].lock();
+ if(!instance[2].previous_owner_dead()){
+ return 1;
+ }
+ *go_ahead = true;
+ }
+ else{
+ std::cout << "launched grandchild" << std::endl;
+ //grandchild locks the lock and dies
+ bool *go_ahead2 = segment.find<bool>("go ahead2").first;
+ assert(go_ahead2);
+ //Lock, flag and die
+ bool try_lock_res = instance[2].try_lock();
+ assert(try_lock_res);
+ if(!try_lock_res){
+ return 1;
+ }
+ *go_ahead2 = true;
+ }
+ }
+ }catch(...){
+ std::cout << "Exception thrown error!" << std::endl;
+ throw;
+ }
+ return 0;
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_TEST_ROBUST_EMULATION_TEST_HEADER
diff --git a/src/boost/libs/interprocess/test/robust_recursive_emulation_test.cpp b/src/boost/libs/interprocess/test/robust_recursive_emulation_test.cpp
new file mode 100644
index 000000000..bc140769b
--- /dev/null
+++ b/src/boost/libs/interprocess/test/robust_recursive_emulation_test.cpp
@@ -0,0 +1,23 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2012. 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 "robust_mutex_test.hpp"
+#include <boost/interprocess/detail/robust_emulation.hpp>
+#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
+
+int main(int argc, char *argv[])
+{
+ using namespace boost::interprocess;
+
+ return test::robust_mutex_test
+ < ipcdetail::robust_spin_mutex<ipcdetail::spin_recursive_mutex> >(argc, argv);
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/segment_manager_test.cpp b/src/boost/libs/interprocess/test/segment_manager_test.cpp
new file mode 100644
index 000000000..1b42c8c5f
--- /dev/null
+++ b/src/boost/libs/interprocess/test/segment_manager_test.cpp
@@ -0,0 +1,478 @@
+#include <boost/interprocess/indexes/flat_map_index.hpp>
+#include <boost/interprocess/indexes/map_index.hpp>
+#include <boost/interprocess/indexes/null_index.hpp>
+#include <boost/interprocess/indexes/unordered_map_index.hpp>
+#include <boost/interprocess/indexes/iset_index.hpp>
+#include <boost/interprocess/indexes/iunordered_set_index.hpp>
+
+#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/segment_manager.hpp>
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/sync/mutex_family.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include "get_process_id_name.hpp"
+#include <cstddef>
+#include <new>
+#include <cstring>
+
+using namespace boost::interprocess;
+
+template <class SegmentManager>
+struct atomic_func_test
+{
+ SegmentManager &rsm;
+ int *object;
+
+ atomic_func_test(SegmentManager &sm)
+ : rsm(sm), object()
+ {}
+
+ void operator()()
+ {
+ object = rsm.template find<int>("atomic_func_find_object").first;
+ }
+ private:
+ atomic_func_test operator=(const atomic_func_test&);
+ atomic_func_test(const atomic_func_test&);
+};
+
+template <class SegmentManager>
+bool test_segment_manager()
+{
+ typedef typename SegmentManager::size_type size_type;
+ const unsigned int ShmSizeSize = 1024*64u;
+ std::string shmname(test::get_process_id_name());
+
+ shared_memory_object::remove(shmname.c_str());
+ shared_memory_object sh_mem( create_only, shmname.c_str(), read_write );
+ sh_mem.truncate( ShmSizeSize );
+ mapped_region mapping( sh_mem, read_write );
+
+ SegmentManager* seg_mgr = new( mapping.get_address() ) SegmentManager( ShmSizeSize );
+ std::size_t free_mem_before = seg_mgr->get_free_memory();
+ std::size_t size_before = seg_mgr->get_size();
+
+ if(size_before != ShmSizeSize)
+ return false;
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ if(seg_mgr->get_min_size() >= ShmSizeSize)
+ return false;
+
+ {//test get_free_memory() / allocate()/deallocate()
+ const size_type Size = ShmSizeSize/2;
+ void *mem = seg_mgr->allocate(Size+1);
+ const size_type free_mem = seg_mgr->get_free_memory();
+ if(free_mem >= Size)
+ return false;
+ if(seg_mgr->all_memory_deallocated())
+ return false;
+ const size_type Size2 = free_mem/2;
+ void *mem2 = seg_mgr->allocate(size_type(Size2+1), std::nothrow);
+ if(seg_mgr->get_free_memory() >= Size2)
+ return false;
+ if(seg_mgr->size(mem) < (Size+1))
+ return false;
+ if(seg_mgr->size(mem2) < (Size2+1))
+ return false;
+ seg_mgr->deallocate(mem);
+ seg_mgr->deallocate(mem2);
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ try{ seg_mgr->allocate(ShmSizeSize*2); }catch(interprocess_exception&){}
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(seg_mgr->allocate(ShmSizeSize*2, std::nothrow))
+ return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ }
+ {//test allocate_aligned
+ const std::size_t Alignment = 128u;
+ void *mem = seg_mgr->allocate_aligned(ShmSizeSize/4, Alignment);
+ if(seg_mgr->all_memory_deallocated())
+ return false;
+ std::size_t offset = static_cast<std::size_t>
+ (static_cast<const char *>(mem) - static_cast<const char *>(mapping.get_address()));
+ if(offset & (Alignment-1))
+ return false;
+ void *mem2 = seg_mgr->allocate_aligned(ShmSizeSize/4, Alignment, std::nothrow);
+ std::size_t offset2 = static_cast<std::size_t>
+ (static_cast<const char *>(mem2) - static_cast<const char *>(mapping.get_address()));
+ if(offset2 & (Alignment-1))
+ return false;
+ seg_mgr->deallocate(mem);
+ seg_mgr->deallocate(mem2);
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ try{ seg_mgr->allocate_aligned(ShmSizeSize*2, Alignment); }catch(interprocess_exception&){}
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(seg_mgr->allocate_aligned(ShmSizeSize*2, Alignment, std::nothrow))
+ return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ }
+ {//test shrink_to_fit
+
+ seg_mgr->shrink_to_fit();
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ std::size_t empty_shrunk_size = seg_mgr->get_size();
+ std::size_t empty_shrunk_free_mem = seg_mgr->get_free_memory();
+ if(empty_shrunk_size >= size_before)
+ return false;
+ if(empty_shrunk_free_mem >= size_before)
+ return false;
+ seg_mgr->grow(size_type(size_before - empty_shrunk_size));
+ if(seg_mgr->get_size() != size_before)
+ return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+ {//test zero_free_memory
+ const size_type Size(ShmSizeSize/2+1), Size2(ShmSizeSize/8);
+ void *mem = seg_mgr->allocate(Size);
+ void *mem2 = seg_mgr->allocate(Size2);
+ //Mark memory to non-zero
+ std::memset(mem, 0xFF, Size);
+ std::memset(mem2, 0xFF, Size2);
+ //Deallocate and check still non-zero
+ seg_mgr->deallocate(mem);
+ seg_mgr->deallocate(mem2);
+ { //Use byte per byte comparison as "static unsigned char zerobuf[Size]"
+ //seems to be problematic in some compilers
+ unsigned char *const mem_uch_ptr = static_cast<unsigned char *>(mem);
+ unsigned char *const mem2_uch_ptr = static_cast<unsigned char *>(mem2);
+ size_type zeroes = 0;
+ for(size_type i = 0; i != Size; ++i){
+ if(!mem_uch_ptr[i])
+ ++zeroes;
+ }
+ if(zeroes == Size)
+ return false;
+
+ zeroes = 0;
+ for(size_type i = 0; i != Size2; ++i){
+ if(!mem2_uch_ptr[i])
+ ++zeroes;
+ }
+ if(zeroes == Size2)
+ return false;
+ }
+ //zero_free_memory and check it's zeroed
+ seg_mgr->zero_free_memory();
+ //TODO: some parts are not zeroed because they are used
+ //as internal metadata, find a way to test this
+ //if(std::memcmp(mem, zerobuf, Size))
+ //return false;
+ //if(std::memcmp(mem2, zerobuf, Size2))
+ //return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+
+ {//test anonymous object
+ int *int_object = seg_mgr->template construct<int>(anonymous_instance)();
+ if(1 != seg_mgr->get_instance_length(int_object))
+ return false;
+ if(anonymous_type != seg_mgr->get_instance_type(int_object))
+ return false;
+ if(seg_mgr->get_instance_name(int_object))
+ return false;
+ seg_mgr->destroy_ptr(int_object);
+ int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int *int_array = seg_mgr->template construct_it<int>(anonymous_instance, std::nothrow)[10](&int_array_values[0]);
+ if(10 != seg_mgr->get_instance_length(int_object))
+ return false;
+ if(anonymous_type != seg_mgr->get_instance_type(int_array))
+ return false;
+ if(seg_mgr->get_instance_name(int_array))
+ return false;
+ seg_mgr->destroy_ptr(int_array);
+ try{ seg_mgr->template construct<int>(anonymous_instance)[ShmSizeSize](); }catch(interprocess_exception&){}
+ if(seg_mgr->template construct<int>(anonymous_instance, std::nothrow)[ShmSizeSize]())
+ try{ seg_mgr->template construct_it<int>(anonymous_instance)[ShmSizeSize](&int_array_values[0]); }catch(interprocess_exception&){}
+ if(seg_mgr->template construct_it<int>(anonymous_instance, std::nothrow)[ShmSizeSize](&int_array_values[0]))
+ return false;
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+
+ {//test named object
+ const char *const object1_name = "object1";
+ const char *const object2_name = "object2";
+ int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+ for(std::size_t i = 0; i != 1/*4*/; ++i){
+ if(seg_mgr->template find<unsigned int>(object1_name).first)
+ return false;
+ //Single element construction
+ unsigned int *uint_object = 0;
+ switch(i){
+ case 0:
+ uint_object = seg_mgr->template construct<unsigned int>(object1_name)();
+ break;
+ case 1:
+ uint_object = seg_mgr->template construct<unsigned int>(object1_name, std::nothrow)();
+ break;
+ case 2:
+ uint_object = seg_mgr->template find_or_construct<unsigned int>(object1_name)();
+ break;
+ case 3:
+ uint_object = seg_mgr->template find_or_construct<unsigned int>(object1_name, std::nothrow)();
+ break;
+ }
+ std::pair<unsigned int*, std::size_t> find_ret = seg_mgr->template find<unsigned int>(object1_name);
+ if(uint_object != find_ret.first)
+ return false;
+ if(1 != find_ret.second)
+ return false;
+ if(1 != seg_mgr->get_instance_length(uint_object))
+ return false;
+ if(named_type != seg_mgr->get_instance_type(uint_object))
+ return false;
+ if(std::strcmp(object1_name, seg_mgr->get_instance_name(uint_object)))
+ return false;
+ //Array construction
+ if(seg_mgr->template find<int>(object2_name).first)
+ return false;
+ int *int_array = 0;
+ switch(i){
+ case 0:
+ int_array = seg_mgr->template construct_it<int>(object2_name)[10](&int_array_values[0]);
+ break;
+ case 1:
+ int_array = seg_mgr->template construct_it<int>(object2_name, std::nothrow)[10](&int_array_values[0]);
+ break;
+ case 2:
+ int_array = seg_mgr->template find_or_construct_it<int>(object2_name)[10](&int_array_values[0]);
+ break;
+ case 3:
+ int_array = seg_mgr->template find_or_construct_it<int>(object2_name, std::nothrow)[10](&int_array_values[0]);
+ break;
+ }
+ std::pair<int*, std::size_t> find_ret2 = seg_mgr->template find<int>(object2_name);
+ if(int_array != find_ret2.first)
+ return false;
+ if(10 != find_ret2.second)
+ return false;
+ if(10 != seg_mgr->get_instance_length(int_array))
+ return false;
+ if(named_type != seg_mgr->get_instance_type(int_array))
+ return false;
+ if(std::strcmp(object2_name, seg_mgr->get_instance_name(int_array)))
+ return false;
+ if(seg_mgr->get_num_named_objects() != 2)
+ return false;
+ typename SegmentManager::const_named_iterator nb(seg_mgr->named_begin());
+ typename SegmentManager::const_named_iterator ne(seg_mgr->named_end());
+ for(std::size_t i = 0, imax = seg_mgr->get_num_named_objects(); i != imax; ++i){ ++nb; }
+ if(nb != ne)
+ return false;
+ seg_mgr->destroy_ptr(uint_object);
+ seg_mgr->template destroy<int>(object2_name);
+ }
+ try{ seg_mgr->template construct<unsigned int>(object1_name)[ShmSizeSize](); }catch(interprocess_exception&){}
+ if(seg_mgr->template construct<int>(object2_name, std::nothrow)[ShmSizeSize]())
+ try{ seg_mgr->template construct_it<unsigned int>(object1_name)[ShmSizeSize](&int_array_values[0]); }catch(interprocess_exception&){}
+ if(seg_mgr->template construct_it<int>(object2_name, std::nothrow)[ShmSizeSize](&int_array_values[0]))
+ return false;
+ seg_mgr->shrink_to_fit_indexes();
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ seg_mgr->reserve_named_objects(1);
+ //In indexes with no capacity() memory won't be allocated so don't check anything was allocated.
+ //if(seg_mgr->all_memory_deallocated()) return false;
+ seg_mgr->shrink_to_fit_indexes();
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+
+ {//test unique object
+ int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+ for(std::size_t i = 0; i != 4; ++i){
+ if(seg_mgr->template find<unsigned int>(unique_instance).first)
+ return false;
+ //Single element construction
+ unsigned int *uint_object = 0;
+ switch(i){
+ case 0:
+ uint_object = seg_mgr->template construct<unsigned int>(unique_instance)();
+ break;
+ case 1:
+ uint_object = seg_mgr->template construct<unsigned int>(unique_instance, std::nothrow)();
+ break;
+ case 2:
+ uint_object = seg_mgr->template find_or_construct<unsigned int>(unique_instance)();
+ break;
+ case 3:
+ uint_object = seg_mgr->template find_or_construct<unsigned int>(unique_instance, std::nothrow)();
+ break;
+ }
+ std::pair<unsigned int*, std::size_t> find_ret = seg_mgr->template find<unsigned int>(unique_instance);
+ if(uint_object != find_ret.first)
+ return false;
+ if(1 != find_ret.second)
+ return false;
+ if(1 != seg_mgr->get_instance_length(uint_object))
+ return false;
+ if(unique_type != seg_mgr->get_instance_type(uint_object))
+ return false;
+ if(std::strcmp(typeid(unsigned int).name(), seg_mgr->get_instance_name(uint_object)))
+ return false;
+ //Array construction
+ if(seg_mgr->template find<int>(unique_instance).first)
+ return false;
+ int *int_array = 0;
+ switch(i){
+ case 0:
+ int_array = seg_mgr->template construct_it<int>(unique_instance)[10](&int_array_values[0]);
+ break;
+ case 1:
+ int_array = seg_mgr->template construct_it<int>(unique_instance, std::nothrow)[10](&int_array_values[0]);
+ break;
+ case 2:
+ int_array = seg_mgr->template find_or_construct_it<int>(unique_instance)[10](&int_array_values[0]);
+ break;
+ case 3:
+ int_array = seg_mgr->template find_or_construct_it<int>(unique_instance, std::nothrow)[10](&int_array_values[0]);
+ break;
+ }
+ std::pair<int*, std::size_t> find_ret2 = seg_mgr->template find<int>(unique_instance);
+ if(int_array != find_ret2.first)
+ return false;
+ if(10 != find_ret2.second)
+ return false;
+ if(10 != seg_mgr->get_instance_length(int_array))
+ return false;
+ if(unique_type != seg_mgr->get_instance_type(int_array))
+ return false;
+ if(std::strcmp(typeid(int).name(), seg_mgr->get_instance_name(int_array)))
+ return false;
+ if(seg_mgr->get_num_unique_objects() != 2)
+ return false;
+ typename SegmentManager::const_unique_iterator nb(seg_mgr->unique_begin());
+ typename SegmentManager::const_unique_iterator ne(seg_mgr->unique_end());
+ for(std::size_t i = 0, imax = seg_mgr->get_num_unique_objects(); i != imax; ++i){ ++nb; }
+ if(nb != ne)
+ return false;
+ seg_mgr->destroy_ptr(uint_object);
+ seg_mgr->template destroy<int>(unique_instance);
+ }
+ try{ seg_mgr->template construct<unsigned int>(unique_instance)[ShmSizeSize](); }catch(interprocess_exception&){}
+ if(seg_mgr->template construct<int>(unique_instance, std::nothrow)[ShmSizeSize]())
+ try{ seg_mgr->template construct_it<unsigned int>(unique_instance)[ShmSizeSize](&int_array_values[0]); }catch(interprocess_exception&){}
+ if(seg_mgr->template construct_it<int>(unique_instance, std::nothrow)[ShmSizeSize](&int_array_values[0]))
+ return false;
+ seg_mgr->shrink_to_fit_indexes();
+ if(seg_mgr->get_free_memory() != free_mem_before)
+ return false;
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ seg_mgr->reserve_unique_objects(1);
+ //In indexes with no capacity() memory won't be allocated so don't check anything was allocated.
+ //if(seg_mgr->all_memory_deallocated()) return false;
+ seg_mgr->shrink_to_fit_indexes();
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+ {//test allocator/deleter
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ typedef typename SegmentManager::template allocator<float>::type allocator_t;
+
+ allocator_t alloc(seg_mgr->template get_allocator<float>());
+
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ offset_ptr<float> f = alloc.allocate(50);
+ if(seg_mgr->all_memory_deallocated())
+ return false;
+ alloc.deallocate(f, 50);
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ typedef typename SegmentManager::template deleter<float>::type deleter_t;
+ deleter_t delet(seg_mgr->template get_deleter<float>());
+ delet(seg_mgr->template construct<float>(anonymous_instance)());
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+ {//test allocator/deleter
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ int *int_object = seg_mgr->template construct<int>("atomic_func_find_object")();
+ atomic_func_test<SegmentManager> func(*seg_mgr);
+ seg_mgr->atomic_func(func);
+ if(int_object != func.object)
+ return 1;
+ seg_mgr->destroy_ptr(int_object);
+ seg_mgr->shrink_to_fit_indexes();
+ if(!seg_mgr->all_memory_deallocated())
+ return false;
+ }
+ return true;
+}
+
+template<class MemoryAlgorithm>
+bool test_each_algo()
+{
+ {
+ typedef segment_manager< char, MemoryAlgorithm, flat_map_index > segment_manager_t;
+ if(!test_segment_manager<segment_manager_t>())
+ return false;
+ }
+ {
+ typedef segment_manager< char, MemoryAlgorithm, map_index > segment_manager_t;
+ if(!test_segment_manager<segment_manager_t>())
+ return false;
+ }
+ /*
+ {
+ typedef segment_manager< char, MemoryAlgorithm, null_index > segment_manager_t;
+ if(!test_segment_manager<segment_manager_t>())
+ return false;
+ }*/
+ /*
+ {
+ typedef segment_manager< char, MemoryAlgorithm, unordered_map_index > segment_manager_t;
+ if(!test_segment_manager<segment_manager_t>())
+ return false;
+ }*/
+ {
+ typedef segment_manager< char, MemoryAlgorithm, iset_index > segment_manager_t;
+ if(!test_segment_manager<segment_manager_t>())
+ return false;
+ }
+ {
+ typedef segment_manager< char, MemoryAlgorithm, iunordered_set_index > segment_manager_t;
+ if(!test_segment_manager<segment_manager_t>())
+ return false;
+ }
+ return true;
+}
+
+int main()
+{
+ if(!test_each_algo< simple_seq_fit< null_mutex_family > >())
+ return 1;
+ if(!test_each_algo< rbtree_best_fit< null_mutex_family > >())
+ return 1;
+
+ return 0;
+}
diff --git a/src/boost/libs/interprocess/test/semaphore_test.cpp b/src/boost/libs/interprocess/test/semaphore_test.cpp
new file mode 100644
index 000000000..54913ce81
--- /dev/null
+++ b/src/boost/libs/interprocess/test/semaphore_test.cpp
@@ -0,0 +1,70 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/sync/interprocess_semaphore.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include "named_creation_template.hpp"
+#include "mutex_test_template.hpp"
+
+static const std::size_t SemCount = 1;
+static const std::size_t RecSemCount = 100;
+
+//This wrapper is necessary to plug this class
+//in named creation tests and interprocess_mutex tests
+class semaphore_test_wrapper
+ : public boost::interprocess::interprocess_semaphore
+{
+ public:
+ semaphore_test_wrapper()
+ : boost::interprocess::interprocess_semaphore(SemCount)
+ {}
+
+ void lock()
+ { this->wait(); }
+
+ bool try_lock()
+ { return this->try_wait(); }
+
+ bool timed_lock(const boost::posix_time::ptime &pt)
+ { return this->timed_wait(pt); }
+
+ void unlock()
+ { this->post(); }
+
+ protected:
+ semaphore_test_wrapper(int initial_count)
+ : boost::interprocess::interprocess_semaphore(initial_count)
+ {}
+};
+
+//This wrapper is necessary to plug this class
+//in recursive tests
+class recursive_semaphore_test_wrapper
+ : public semaphore_test_wrapper
+{
+ public:
+ recursive_semaphore_test_wrapper()
+ : semaphore_test_wrapper(RecSemCount)
+ {}
+};
+
+int main ()
+{
+ using namespace boost::interprocess;
+
+ test::test_all_lock<semaphore_test_wrapper>();
+ test::test_all_recursive_lock<recursive_semaphore_test_wrapper>();
+ test::test_all_mutex<semaphore_test_wrapper>();
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/set_test.hpp b/src/boost/libs/interprocess/test/set_test.hpp
new file mode 100644
index 000000000..44b0b66e7
--- /dev/null
+++ b/src/boost/libs/interprocess/test/set_test.hpp
@@ -0,0 +1,594 @@
+////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_TEST_SET_TEST_HEADER
+#define BOOST_INTERPROCESS_TEST_SET_TEST_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include "check_equal_containers.hpp"
+#include "print_container.hpp"
+#include <boost/move/utility_core.hpp>
+#include "get_process_id_name.hpp"
+
+#include <functional>
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template<class ManagedSharedMemory
+ ,class MyShmSet
+ ,class MyStdSet
+ ,class MyShmMultiSet
+ ,class MyStdMultiSet>
+int set_test ()
+{
+ typedef typename MyShmSet::value_type IntType;
+ const int memsize = 65536;
+ const char *const shMemName = test::get_process_id_name();
+ const int max = 100;
+
+ try{
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ ManagedSharedMemory segment(create_only, shMemName, memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmSet *shmset =
+ segment.template construct<MyShmSet>("MyShmSet")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdSet *stdset = new MyStdSet;
+
+ MyShmMultiSet *shmmultiset =
+ segment.template construct<MyShmMultiSet>("MyShmMultiSet")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiSet *stdmultiset = new MyStdMultiSet;
+
+ //Test construction from a range
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(i/2);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = i/2;
+ }
+ IntType aux_vect3[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(i/2);
+ aux_vect3[i] = boost::move(move_me);
+ }
+
+ MyShmSet *shmset2 =
+ segment.template construct<MyShmSet>("MyShmSet2")
+ ( ::boost::make_move_iterator(&aux_vect[0])
+ , ::boost::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")
+ ( ::boost::make_move_iterator(&aux_vect3[0])
+ , ::boost::make_move_iterator(aux_vect3 + 50)
+ , std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
+ if(!CheckEqualContainers(shmset2, stdset2)){
+ std::cout << "Error in construct<MyShmSet>(MyShmSet2)" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset2, stdmultiset2)){
+ std::cout << "Error in construct<MyShmMultiSet>(MyShmMultiSet2)" << std::endl;
+ return 1;
+ }
+
+ //ordered range insertion
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(i);
+ aux_vect[i] = boost::move(move_me);
+ }
+
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = i;
+ }
+
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(i);
+ aux_vect3[i] = boost::move(move_me);
+ }
+
+ MyShmSet *shmset3 =
+ segment.template construct<MyShmSet>("MyShmSet3")
+ ( ordered_unique_range
+ , ::boost::make_move_iterator(&aux_vect[0])
+ , ::boost::make_move_iterator(aux_vect + 50)
+ , std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
+
+ MyShmMultiSet *shmmultiset3 =
+ segment.template construct<MyShmMultiSet>("MyShmMultiSet3")
+ ( ordered_range
+ , ::boost::make_move_iterator(&aux_vect3[0])
+ , ::boost::make_move_iterator(aux_vect3 + 50)
+ , std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiSet *stdmultiset3 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
+
+ if(!CheckEqualContainers(shmset3, stdset3)){
+ std::cout << "Error in construct<MyShmSet>(MyShmSet3)" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset3, stdmultiset3)){
+ std::cout << "Error in construct<MyShmMultiSet>(MyShmMultiSet3)" << std::endl;
+ return 1;
+ }
+
+ segment.destroy_ptr(shmset2);
+ segment.destroy_ptr(shmmultiset2);
+ delete stdset2;
+ delete stdmultiset2;
+
+ segment.destroy_ptr(shmset3);
+ segment.destroy_ptr(shmmultiset3);
+ delete stdset3;
+ delete stdmultiset3;
+ }
+
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
+ return 1;
+ }
+
+ for(int i = 0; i < max/2; ++i){
+ IntType move_me(i);
+ shmset->insert(boost::move(move_me));
+ stdset->insert(i);
+ IntType move_me2(i);
+ shmmultiset->insert(boost::move(move_me2));
+ stdmultiset->insert(i);
+
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
+ return 1;
+ }
+ //
+ shmset->insert(IntType(i));
+ stdset->insert(i);
+ shmmultiset->insert(IntType(i));
+ stdmultiset->insert(i);
+
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
+ return 1;
+ }
+
+ }
+
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(boost::move(move_me)" << std::endl;
+ return 1;
+ }
+
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(boost::move(move_me)" << std::endl;
+ return 1;
+ }
+
+ typename MyShmSet::iterator it;
+ typename MyShmSet::const_iterator cit = it;
+ (void)cit;
+
+ shmset->erase(shmset->begin()++);
+ stdset->erase(stdset->begin()++);
+ shmmultiset->erase(shmmultiset->begin()++);
+ stdmultiset->erase(stdmultiset->begin()++);
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->erase(shmset->begin()++)" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->erase(shmmultiset->begin()++)" << std::endl;
+ return 1;
+ }
+
+ shmset->erase(shmset->begin());
+ stdset->erase(stdset->begin());
+ shmmultiset->erase(shmmultiset->begin());
+ stdmultiset->erase(stdmultiset->begin());
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->erase(shmset->begin())" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->erase(shmmultiset->begin())" << std::endl;
+ return 1;
+ }
+
+ //Swapping test
+ std::less<IntType> lessfunc;
+ MyShmSet tmpshmeset2 (lessfunc, segment.get_segment_manager());
+ MyStdSet tmpstdset2;
+ MyShmMultiSet tmpshmemultiset2(lessfunc, segment.get_segment_manager());
+ MyStdMultiSet tmpstdmultiset2;
+ shmset->swap(tmpshmeset2);
+ stdset->swap(tmpstdset2);
+ shmmultiset->swap(tmpshmemultiset2);
+ stdmultiset->swap(tmpstdmultiset2);
+ shmset->swap(tmpshmeset2);
+ stdset->swap(tmpstdset2);
+ shmmultiset->swap(tmpshmemultiset2);
+ stdmultiset->swap(tmpstdmultiset2);
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->swap(tmpshmeset2)" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->swap(tmpshmemultiset2)" << std::endl;
+ return 1;
+ }
+
+ //Insertion from other container
+ //Initialize values
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ IntType aux_vect3[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect3[i] = boost::move(move_me);
+ }
+
+ shmset->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
+ stdset->insert(aux_vect2, aux_vect2 + 50);
+ shmmultiset->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
+ stdmultiset->insert(aux_vect2, aux_vect2 + 50);
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(::boost::make_move_iterator(&aux_vect[0])..." << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(::boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
+ return 1;
+ }
+
+ for(int i = 0, j = static_cast<int>(shmset->size()); i < j; ++i){
+ IntType erase_me(i);
+ shmset->erase(erase_me);
+ stdset->erase(i);
+ shmmultiset->erase(erase_me);
+ stdmultiset->erase(i);
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->erase(erase_me)" << shmset->size() << " " << stdset->size() << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->erase(erase_me)" << std::endl;
+ return 1;
+ }
+ }
+ }
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ IntType aux_vect3[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect3[i] = boost::move(move_me);
+ }
+
+ IntType aux_vect4[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect4[i] = boost::move(move_me);
+ }
+
+ IntType aux_vect5[50];
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect5[i] = boost::move(move_me);
+ }
+
+ shmset->insert(::boost::make_move_iterator(&aux_vect[0]), ::boost::make_move_iterator(aux_vect + 50));
+ shmset->insert(::boost::make_move_iterator(&aux_vect3[0]), ::boost::make_move_iterator(aux_vect3 + 50));
+ stdset->insert(aux_vect2, aux_vect2 + 50);
+ stdset->insert(aux_vect2, aux_vect2 + 50);
+ shmmultiset->insert(::boost::make_move_iterator(&aux_vect4[0]), ::boost::make_move_iterator(aux_vect4 + 50));
+ shmmultiset->insert(::boost::make_move_iterator(&aux_vect5[0]), ::boost::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(::boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(::boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
+ return 1;
+ }
+
+ shmset->erase(*shmset->begin());
+ stdset->erase(*stdset->begin());
+ shmmultiset->erase(*shmmultiset->begin());
+ stdmultiset->erase(*stdmultiset->begin());
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->erase(*shmset->begin())" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->erase(*shmmultiset->begin())" << std::endl;
+ return 1;
+ }
+ }
+
+ for(int i = 0; i < max/2; ++i){
+ IntType move_me(i);
+ shmset->insert(shmset->begin(), boost::move(move_me));
+ stdset->insert(stdset->begin(), i);
+ IntType move_me2(i);
+ shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2));
+ stdmultiset->insert(stdmultiset->begin(), i);
+ //
+ shmset->insert(shmset->begin(), IntType(i));
+ stdset->insert(stdset->begin(), i);
+ shmmultiset->insert(shmmultiset->begin(), IntType(i));
+ stdmultiset->insert(stdmultiset->begin(), i);
+ }
+
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(boost::move(move_me)) try 2" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(boost::move(move_me2)) try 2" << std::endl;
+ return 1;
+ }
+
+ for(int i = 0; i < max; ++i){
+ {
+ IntType move_me(i);
+ shmset->insert(shmset->begin(), boost::move(move_me));
+ stdset->insert(stdset->begin(), i);
+ //PrintContainers(shmset, stdset);
+ IntType move_me2(i);
+ shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2));
+ stdmultiset->insert(stdmultiset->begin(), i);
+ //PrintContainers(shmmultiset, stdmultiset);
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(shmset->begin(), boost::move(move_me))" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(shmmultiset->begin(), boost::move(move_me2))" << std::endl;
+ return 1;
+ }
+
+ IntType move_me3(i);
+ shmset->insert(shmset->end(), boost::move(move_me3));
+ stdset->insert(stdset->end(), i);
+ IntType move_me4(i);
+ shmmultiset->insert(shmmultiset->end(), boost::move(move_me4));
+ stdmultiset->insert(stdmultiset->end(), i);
+ if(!CheckEqualContainers(shmset, stdset)){
+ std::cout << "Error in shmset->insert(shmset->end(), boost::move(move_me3))" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(shmmultiset->end(), boost::move(move_me4))" << std::endl;
+ return 1;
+ }
+ }
+ {
+ IntType move_me(i);
+ shmset->insert(shmset->upper_bound(move_me), boost::move(move_me));
+ stdset->insert(stdset->upper_bound(i), i);
+ //PrintContainers(shmset, stdset);
+ IntType move_me2(i);
+ shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::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), boost::move(move_me))" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(shmmultiset->upper_bound(move_me2), boost::move(move_me2))" << std::endl;
+ return 1;
+ }
+ }
+ {
+ IntType move_me(i);
+ IntType move_me2(i);
+ shmset->insert(shmset->lower_bound(move_me), boost::move(move_me2));
+ stdset->insert(stdset->lower_bound(i), i);
+ //PrintContainers(shmset, stdset);
+ move_me2 = i;
+ shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::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), boost::move(move_me2))" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)){
+ std::cout << "Error in shmmultiset->insert(shmmultiset->lower_bound(move_me2), boost::move(move_me2))" << std::endl;
+ return 1;
+ }
+ }
+ }
+
+ //Compare count with std containers
+ for(int i = 0; i < max; ++i){
+ IntType count_me(i);
+ if(shmset->count(count_me) != stdset->count(i)){
+ return -1;
+ }
+ if(shmmultiset->count(count_me) != stdmultiset->count(i)){
+ return -1;
+ }
+ }
+
+ //Now do count exercise
+ shmset->erase(shmset->begin(), shmset->end());
+ shmmultiset->erase(shmmultiset->begin(), shmmultiset->end());
+ shmset->clear();
+ shmmultiset->clear();
+
+ for(int j = 0; j < 3; ++j)
+ for(int i = 0; i < 100; ++i){
+ IntType move_me(i);
+ shmset->insert(boost::move(move_me));
+ IntType move_me2(i);
+ shmmultiset->insert(boost::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;
+ return 1;
+ }
+ if(shmmultiset->count(count_me) != typename MyShmMultiSet::size_type(j+1)){
+ std::cout << "Error in shmmultiset->count(count_me)" << std::endl;
+ return 1;
+ }
+ }
+
+ segment.template destroy<MyShmSet>("MyShmSet");
+ delete stdset;
+ segment.destroy_ptr(shmmultiset);
+ delete stdmultiset;
+ segment.shrink_to_fit_indexes();
+
+ if(!segment.all_memory_deallocated()){
+ std::cout << "Error in segment.all_memory_deallocated()" << std::endl;
+ return 1;
+ }
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+template<class ManagedSharedMemory
+ ,class MyShmSet
+ ,class MyStdSet
+ ,class MyShmMultiSet
+ ,class MyStdMultiSet>
+int set_test_copyable ()
+{
+ typedef typename MyShmSet::value_type IntType;
+ const int memsize = 65536;
+ const char *const shMemName = test::get_process_id_name();
+ const int max = 100;
+
+ try{
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ ManagedSharedMemory segment(create_only, shMemName, memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmSet *shmset =
+ segment.template construct<MyShmSet>("MyShmSet")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdSet *stdset = new MyStdSet;
+
+ MyShmMultiSet *shmmultiset =
+ segment.template construct<MyShmMultiSet>("MyShmMultiSet")
+ (std::less<IntType>(), segment.get_segment_manager());
+
+ MyStdMultiSet *stdmultiset = new MyStdMultiSet;
+
+ for(int i = 0; i < max; ++i){
+ IntType move_me(i);
+ shmset->insert(boost::move(move_me));
+ stdset->insert(i);
+ IntType move_me2(i);
+ shmmultiset->insert(boost::move(move_me2));
+ stdmultiset->insert(i);
+ }
+ if(!CheckEqualContainers(shmset, stdset)) return 1;
+ if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
+
+ {
+ //Now, test copy constructor
+ MyShmSet shmsetcopy(*shmset);
+ MyStdSet stdsetcopy(*stdset);
+
+ if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
+ return 1;
+
+ MyShmMultiSet shmmsetcopy(*shmmultiset);
+ MyStdMultiSet stdmsetcopy(*stdmultiset);
+
+ if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
+ return 1;
+
+ //And now assignment
+ shmsetcopy = *shmset;
+ stdsetcopy = *stdset;
+
+ if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
+ return 1;
+
+ shmmsetcopy = *shmmultiset;
+ stdmsetcopy = *stdmultiset;
+
+ if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
+ return 1;
+ }
+ segment.destroy_ptr(shmset);
+ segment.destroy_ptr(shmmultiset);
+ delete stdset;
+ delete stdmultiset;
+ segment.shrink_to_fit_indexes();
+ if(!segment.all_memory_deallocated())
+ return 1;
+ }
+ catch(...){
+ shared_memory_object::remove(shMemName);
+ throw;
+ }
+ shared_memory_object::remove(shMemName);
+ return 0;
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif
diff --git a/src/boost/libs/interprocess/test/sharable_mutex_test.cpp b/src/boost/libs/interprocess/test/sharable_mutex_test.cpp
new file mode 100644
index 000000000..b27315451
--- /dev/null
+++ b/src/boost/libs/interprocess/test/sharable_mutex_test.cpp
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 "mutex_test_template.hpp"
+#include "sharable_mutex_test_template.hpp"
+#include <boost/interprocess/sync/interprocess_sharable_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/sharable_lock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include "util.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+
+ test::test_all_lock<interprocess_sharable_mutex>();
+ test::test_all_mutex<interprocess_sharable_mutex>();
+ test::test_all_sharable_mutex<interprocess_sharable_mutex>();
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/sharable_mutex_test_template.hpp b/src/boost/libs/interprocess/test/sharable_mutex_test_template.hpp
new file mode 100644
index 000000000..3c14c7a74
--- /dev/null
+++ b/src/boost/libs/interprocess/test/sharable_mutex_test_template.hpp
@@ -0,0 +1,291 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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. William E. Kempf 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-2012. 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_TEST_SHARABLE_MUTEX_TEST_TEMPLATE_HEADER
+#define BOOST_INTERPROCESS_TEST_SHARABLE_MUTEX_TEST_TEMPLATE_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include "boost_interprocess_check.hpp"
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/interprocess/sync/sharable_lock.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <iostream>
+#include <cassert>
+#include "util.hpp"
+
+namespace boost { namespace interprocess { namespace test {
+
+template<typename SM>
+void plain_exclusive(void *arg, SM &sm)
+{
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
+ boost::interprocess::scoped_lock<SM> l(sm);
+ boost::interprocess::ipcdetail::thread_sleep((1000*3*BaseSeconds));
+ shared_val += 10;
+ pdata->m_value = shared_val;
+}
+
+template<typename SM>
+void plain_shared(void *arg, SM &sm)
+{
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
+ boost::interprocess::sharable_lock<SM> l(sm);
+ if(pdata->m_secs){
+ boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs*BaseSeconds));
+ }
+ pdata->m_value = shared_val;
+}
+
+template<typename SM>
+void try_exclusive(void *arg, SM &sm)
+{
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
+ boost::interprocess::scoped_lock<SM> l(sm, boost::interprocess::defer_lock);
+ if (l.try_lock()){
+ boost::interprocess::ipcdetail::thread_sleep((1000*3*BaseSeconds));
+ shared_val += 10;
+ pdata->m_value = shared_val;
+ }
+}
+
+template<typename SM>
+void try_shared(void *arg, SM &sm)
+{
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
+ boost::interprocess::sharable_lock<SM> l(sm, boost::interprocess::defer_lock);
+ if (l.try_lock()){
+ if(pdata->m_secs){
+ boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs*BaseSeconds));
+ }
+ pdata->m_value = shared_val;
+ }
+}
+
+template<typename SM>
+void timed_exclusive(void *arg, SM &sm)
+{
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
+ boost::posix_time::ptime pt(delay(pdata->m_secs));
+ boost::interprocess::scoped_lock<SM>
+ l (sm, boost::interprocess::defer_lock);
+ if (l.timed_lock(pt)){
+ boost::interprocess::ipcdetail::thread_sleep((1000*3*BaseSeconds));
+ shared_val += 10;
+ pdata->m_value = shared_val;
+ }
+}
+
+template<typename SM>
+void timed_shared(void *arg, SM &sm)
+{
+ data<SM> *pdata = static_cast<data<SM>*>(arg);
+ boost::posix_time::ptime pt(delay(pdata->m_secs));
+ boost::interprocess::sharable_lock<SM>
+ l(sm, boost::interprocess::defer_lock);
+ if (l.timed_lock(pt)){
+ if(pdata->m_secs){
+ boost::interprocess::ipcdetail::thread_sleep((1000*pdata->m_secs*BaseSeconds));
+ }
+ pdata->m_value = shared_val;
+ }
+}
+
+template<typename SM>
+void test_plain_sharable_mutex()
+{
+ {
+ shared_val = 0;
+ SM mtx;
+ data<SM> s1(1);
+ data<SM> s2(2);
+ data<SM> e1(1);
+ data<SM> e2(2);
+
+ // Writer one launches, holds the lock for 3*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tw1;
+ boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(plain_exclusive, &e1, mtx));
+
+ // Writer two launches, tries to grab the lock, "clearly"
+ // after Writer one will already be holding it.
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+ boost::interprocess::ipcdetail::OS_thread_t tw2;
+ boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(plain_exclusive, &e2, mtx));
+
+ // Reader one launches, "clearly" after writer two, and "clearly"
+ // while writer 1 still holds the lock
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+ boost::interprocess::ipcdetail::OS_thread_t thr1;
+ boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(plain_shared,&s1, mtx));
+ boost::interprocess::ipcdetail::OS_thread_t thr2;
+ boost::interprocess::ipcdetail::thread_launch(thr2, thread_adapter<SM>(plain_shared,&s2, mtx));
+
+ boost::interprocess::ipcdetail::thread_join(thr2);
+ boost::interprocess::ipcdetail::thread_join(thr1);
+ boost::interprocess::ipcdetail::thread_join(tw2);
+ boost::interprocess::ipcdetail::thread_join(tw1);
+
+ //We can only assure that the writer will be first
+ BOOST_INTERPROCESS_CHECK(e1.m_value == 10);
+ //A that we will execute all
+ BOOST_INTERPROCESS_CHECK(s1.m_value == 20 || s2.m_value == 20 || e2.m_value == 20);
+ }
+
+ {
+ shared_val = 0;
+ SM mtx;
+
+ data<SM> s1(1, 3);
+ data<SM> s2(2, 3);
+ data<SM> e1(1);
+ data<SM> e2(2);
+
+ //We launch 2 readers, that will block for 3*BaseTime seconds
+ boost::interprocess::ipcdetail::OS_thread_t thr1;
+ boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(plain_shared,&s1, mtx));
+ boost::interprocess::ipcdetail::OS_thread_t thr2;
+ boost::interprocess::ipcdetail::thread_launch(thr2, thread_adapter<SM>(plain_shared,&s2, mtx));
+
+ //Make sure they try to hold the sharable lock
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+
+ // We launch two writers, that should block until the readers end
+ boost::interprocess::ipcdetail::OS_thread_t tw1;
+ boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(plain_exclusive,&e1, mtx));
+
+ boost::interprocess::ipcdetail::OS_thread_t tw2;
+ boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(plain_exclusive,&e2, mtx));
+
+ boost::interprocess::ipcdetail::thread_join(thr2);
+ boost::interprocess::ipcdetail::thread_join(thr1);
+ boost::interprocess::ipcdetail::thread_join(tw2);
+ boost::interprocess::ipcdetail::thread_join(tw1);
+
+ //We can only assure that the shared will finish first...
+ BOOST_INTERPROCESS_CHECK(s1.m_value == 0 || s2.m_value == 0);
+ //...and writers will be mutually excluded after readers
+ BOOST_INTERPROCESS_CHECK((e1.m_value == 10 && e2.m_value == 20) ||
+ (e1.m_value == 20 && e2.m_value == 10) );
+ }
+}
+
+template<typename SM>
+void test_try_sharable_mutex()
+{
+ SM mtx;
+
+ data<SM> s1(1);
+ data<SM> e1(2);
+ data<SM> e2(3);
+
+ // We start with some specialized tests for "try" behavior
+
+ shared_val = 0;
+
+ // Writer one launches, holds the lock for 3*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tw1;
+ boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(try_exclusive,&e1,mtx));
+
+ // Reader one launches, "clearly" after writer #1 holds the lock
+ // and before it releases the lock.
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+ boost::interprocess::ipcdetail::OS_thread_t thr1;
+ boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(try_shared,&s1,mtx));
+
+ // Writer two launches in the same timeframe.
+ boost::interprocess::ipcdetail::OS_thread_t tw2;
+ boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(try_exclusive,&e2,mtx));
+
+ boost::interprocess::ipcdetail::thread_join(tw2);
+ boost::interprocess::ipcdetail::thread_join(thr1);
+ boost::interprocess::ipcdetail::thread_join(tw1);
+
+ BOOST_INTERPROCESS_CHECK(e1.m_value == 10);
+ BOOST_INTERPROCESS_CHECK(s1.m_value == -1); // Try would return w/o waiting
+ BOOST_INTERPROCESS_CHECK(e2.m_value == -1); // Try would return w/o waiting
+}
+
+template<typename SM>
+void test_timed_sharable_mutex()
+{
+ SM mtx;
+ data<SM> s1(1,1*BaseSeconds);
+ data<SM> s2(2,3*BaseSeconds);
+ data<SM> e1(3,3*BaseSeconds);
+ data<SM> e2(4,1*BaseSeconds);
+
+ // We begin with some specialized tests for "timed" behavior
+
+ shared_val = 0;
+
+ // Writer one will hold the lock for 3*BaseSeconds seconds.
+ boost::interprocess::ipcdetail::OS_thread_t tw1;
+ boost::interprocess::ipcdetail::thread_launch(tw1, thread_adapter<SM>(timed_exclusive,&e1,mtx));
+
+ boost::interprocess::ipcdetail::thread_sleep((1000*1*BaseSeconds));
+ // Writer two will "clearly" try for the lock after the readers
+ // have tried for it. Writer will wait up 1*BaseSeconds seconds for the lock.
+ // This write will fail.
+ boost::interprocess::ipcdetail::OS_thread_t tw2;
+ boost::interprocess::ipcdetail::thread_launch(tw2, thread_adapter<SM>(timed_exclusive,&e2,mtx));
+
+ // Readers one and two will "clearly" try for the lock after writer
+ // one already holds it. 1st reader will wait 1*BaseSeconds seconds, and will fail
+ // to get the lock. 2nd reader will wait 3*BaseSeconds seconds, and will get
+ // the lock.
+
+ boost::interprocess::ipcdetail::OS_thread_t thr1;
+ boost::interprocess::ipcdetail::thread_launch(thr1, thread_adapter<SM>(timed_shared,&s1,mtx));
+
+ boost::interprocess::ipcdetail::OS_thread_t thr2;
+ boost::interprocess::ipcdetail::thread_launch(thr2, thread_adapter<SM>(timed_shared,&s2,mtx));
+
+ boost::interprocess::ipcdetail::thread_join(tw1);
+ boost::interprocess::ipcdetail::thread_join(thr1);
+ boost::interprocess::ipcdetail::thread_join(thr2);
+ boost::interprocess::ipcdetail::thread_join(tw2);
+
+ BOOST_INTERPROCESS_CHECK(e1.m_value == 10);
+ BOOST_INTERPROCESS_CHECK(s1.m_value == -1);
+ BOOST_INTERPROCESS_CHECK(s2.m_value == 10);
+ BOOST_INTERPROCESS_CHECK(e2.m_value == -1);
+}
+
+template<typename SM>
+void test_all_sharable_mutex()
+{
+ std::cout << "test_plain_sharable_mutex<" << typeid(SM).name() << ">" << std::endl;
+ test_plain_sharable_mutex<SM>();
+
+ std::cout << "test_try_sharable_mutex<" << typeid(SM).name() << ">" << std::endl;
+ test_try_sharable_mutex<SM>();
+
+ std::cout << "test_timed_sharable_mutex<" << typeid(SM).name() << ">" << std::endl;
+ test_timed_sharable_mutex<SM>();
+}
+
+
+}}} //namespace boost { namespace interprocess { namespace test {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_SHARABLE_MUTEX_TEST_TEMPLATE_HEADER
diff --git a/src/boost/libs/interprocess/test/shared_memory_mapping_test.cpp b/src/boost/libs/interprocess/test/shared_memory_mapping_test.cpp
new file mode 100644
index 000000000..a3b0f1051
--- /dev/null
+++ b/src/boost/libs/interprocess/test/shared_memory_mapping_test.cpp
@@ -0,0 +1,239 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <fstream>
+#include <iostream>
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/anonymous_shared_memory.hpp>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+shared_memory_object get_shared_memory_mapping()
+{
+ shared_memory_object sh;
+ return shared_memory_object(boost::move(sh));
+}
+
+int main ()
+{
+ std::string process_id = test::get_process_id_name();
+ std::string process_id2(process_id);
+ process_id2 += "_2";
+ try{
+ const std::size_t FileSize = 99999*4;
+ {
+ //Remove shared memory
+ shared_memory_object::remove(process_id.c_str());
+ shared_memory_object::remove(process_id2.c_str());
+
+ //Create shared memory and file mapping
+ shared_memory_object mapping(create_only, process_id.c_str(), read_write);
+ mapping.truncate(FileSize);
+ }
+
+ {
+ //Create a file mapping
+ shared_memory_object mapping(open_only, process_id.c_str(), read_write);
+
+ //Create two mapped regions, one half of the file each
+ mapped_region region (mapping
+ ,read_write
+ ,0
+ ,FileSize/2
+ ,0);
+
+ mapped_region region2(mapping
+ ,read_write
+ ,FileSize/2
+ ,FileSize - FileSize/2
+ ,0);
+
+ //Fill two regions with a pattern
+ unsigned char *filler = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+
+ filler = static_cast<unsigned char*>(region2.get_address());
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+ if(!region.flush(0, 0, false)){
+ return 1;
+ }
+
+ if(!region2.flush(0, 0, true)){
+ return 1;
+ }
+ }
+
+ //See if the pattern is correct in the file using two mapped regions
+ {
+ //Create a file mapping
+ shared_memory_object mapping(open_only, process_id.c_str(), read_write);
+ mapped_region region(mapping, read_write, 0, FileSize/2, 0);
+ mapped_region region2(mapping, read_write, FileSize/2, FileSize - FileSize/2, 0);
+
+ unsigned char *checker = static_cast<unsigned char*>(region.get_address());
+ //Check pattern
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+
+ //Check second half
+ checker = static_cast<unsigned char *>(region2.get_address());
+
+ //Check pattern
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+
+ //Now check the pattern mapping a single read only mapped_region
+ {
+ //Create a file mapping
+ shared_memory_object mapping(open_only, process_id.c_str(), read_only);
+
+ //Create a single regions, mapping all the file
+ mapped_region region (mapping, read_only);
+
+ //Check pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ //Now shrink
+ const std::size_t original_region_size = region.get_size();
+ if(!region.shrink_by(region.get_size()/2, false) || region.get_size() != original_region_size/2){
+ return 1;
+ }
+ const std::size_t shrunk_region_size = region.get_size();
+ if(!region.shrink_by(region.get_size()/2, true) || region.get_size() != shrunk_region_size/2){
+ return 1;
+ }
+
+ //Now advise
+ #if defined(POSIX_MADV_NORMAL) || defined(MADV_NORMAL)
+ std::cout << "Advice normal" << std::endl;
+ if(!region.advise(mapped_region::advice_normal)){
+ return 1;
+ }
+ #endif
+
+ #if defined(POSIX_MADV_SEQUENTIAL) || defined(MADV_SEQUENTIAL)
+ std::cout << "Advice sequential" << std::endl;
+ if(!region.advise(mapped_region::advice_sequential)){
+ return 1;
+ }
+ #endif
+
+ #if defined(POSIX_MADV_RANDOM) || defined(MADV_RANDOM)
+ std::cout << "Advice random" << std::endl;
+ if(!region.advise(mapped_region::advice_random)){
+ return 1;
+ }
+ #endif
+
+ #if defined(POSIX_MADV_WILLNEED) || defined(MADV_WILLNEED)
+ std::cout << "Advice 'will need'" << std::endl;
+ if(!region.advise(mapped_region::advice_willneed)){
+ return 1;
+ }
+ #endif
+
+ #if defined(POSIX_MADV_DONTNEED) || (defined(MADV_DONTNEED) && defined(BOOST_INTERPROCESS_MADV_DONTNEED_HAS_NONDESTRUCTIVE_SEMANTICS))
+ std::cout << "Advice 'dont't need'" << std::endl;
+ if(!region.advise(mapped_region::advice_dontneed)){
+ return 1;
+ }
+ #endif
+
+ }
+ {
+ //Check for busy address space
+ shared_memory_object mapping(open_only, process_id.c_str(), read_only);
+ mapped_region region (mapping, read_only);
+ shared_memory_object mapping2(create_only, process_id2.c_str(), read_write);
+ mapping2.truncate(FileSize);
+ try{
+ mapped_region region2 (mapping2, read_only, 0, FileSize, region.get_address());
+ }
+ catch(interprocess_exception &e){
+ shared_memory_object::remove(process_id2.c_str());
+ if(e.get_error_code() != busy_error){
+ throw e;
+ }
+ }
+ catch(std::exception &){
+ shared_memory_object::remove(process_id2.c_str());
+ throw;
+ }
+ shared_memory_object::remove(process_id2.c_str());
+ }
+ {
+ //Now check anonymous mapping
+ mapped_region region(anonymous_shared_memory(FileSize));
+
+ //Write pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ *pattern = static_cast<unsigned char>(i);
+ }
+
+ //Check pattern
+ pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+ {
+ //Now test move semantics
+ shared_memory_object mapping(open_only, process_id.c_str(), read_write);
+ shared_memory_object move_ctor(boost::move(mapping));
+ shared_memory_object move_assign;
+ move_assign = boost::move(move_ctor);
+ shared_memory_object ret(get_shared_memory_mapping());
+ }
+ }
+ catch(std::exception &exc){
+ shared_memory_object::remove(process_id.c_str());
+ shared_memory_object::remove(process_id2.c_str());
+ std::cout << "Unhandled exception: " << exc.what() << std::endl;
+ return 1;
+ }
+ shared_memory_object::remove(process_id.c_str());
+ return 0;
+}
diff --git a/src/boost/libs/interprocess/test/shared_memory_test.cpp b/src/boost/libs/interprocess/test/shared_memory_test.cpp
new file mode 100644
index 000000000..0723e3866
--- /dev/null
+++ b/src/boost/libs/interprocess/test/shared_memory_test.cpp
@@ -0,0 +1,87 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/shared_memory_object.hpp>
+#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include "named_creation_template.hpp"
+#include <cstring> //for strcmp, memset
+#include <iostream> //for cout
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+static const std::size_t ShmSize = 1000;
+static const char * ShmName = test::get_process_id_name();
+
+struct eraser
+{
+ ~eraser()
+ {
+ shared_memory_object::remove(ShmName);
+ }
+};
+
+typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> 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 shared_memory
+{
+
+ public:
+ shared_memory_creation_test_wrapper(create_only_t)
+ : shared_memory(create_only, ShmName, ShmSize, read_write, 0, permissions())
+ {}
+
+ shared_memory_creation_test_wrapper(open_only_t)
+ : shared_memory(open_only, ShmName, read_write, 0)
+ {}
+
+ shared_memory_creation_test_wrapper(open_or_create_t)
+ : shared_memory(open_or_create, ShmName, ShmSize, read_write, 0, permissions())
+ {}
+};
+
+
+int main ()
+{
+ try{
+ shared_memory_object::remove(ShmName);
+ test::test_named_creation<shared_memory_creation_test_wrapper>();
+
+ //Create and get name, size and address
+ {
+ shared_memory_object::remove(ShmName);
+ shared_memory shm1(create_only, ShmName, ShmSize, read_write, 0, permissions());
+
+ //Overwrite all memory
+ std::memset(shm1.get_user_address(), 0, shm1.get_user_size());
+
+ //Now test move semantics
+ shared_memory move_ctor(boost::move(shm1));
+ shared_memory move_assign;
+ move_assign = boost::move(move_ctor);
+ }
+ }
+ catch(std::exception &ex){
+ shared_memory_object::remove(ShmName);
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ shared_memory_object::remove(ShmName);
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/shared_ptr_test.cpp b/src/boost/libs/interprocess/test/shared_ptr_test.cpp
new file mode 100644
index 000000000..17858459c
--- /dev/null
+++ b/src/boost/libs/interprocess/test/shared_ptr_test.cpp
@@ -0,0 +1,615 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Peter Dimov 2002-2005, 2007.
+// (C) Copyright Ion Gaztanaga 2006-2012.
+// 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/offset_ptr.hpp>
+#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
+#include <boost/interprocess/smart_ptr/weak_ptr.hpp>
+#include <boost/interprocess/smart_ptr/enable_shared_from_this.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/string.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
+#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
+#include <boost/core/lightweight_test.hpp>
+#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
+{
+ public:
+ virtual ~base_class()
+ {}
+};
+
+class derived_class
+ : public base_class
+{
+ public:
+ virtual ~derived_class()
+ {}
+};
+
+int simple_test()
+{
+ typedef managed_shared_memory::segment_manager segment_mngr_t;
+ typedef allocator<base_class, segment_mngr_t> base_class_allocator;
+ typedef deleter<base_class, segment_mngr_t> base_deleter_t;
+ typedef shared_ptr<base_class, base_class_allocator, base_deleter_t> base_shared_ptr;
+
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ shared_memory_object::remove(process_name.c_str());
+ {
+ managed_shared_memory shmem(create_only, process_name.c_str(), 10000);
+
+ {
+ base_shared_ptr s_ptr(base_shared_ptr::pointer(0),
+ base_class_allocator(shmem.get_segment_manager()),
+ base_deleter_t(shmem.get_segment_manager()));
+
+ base_shared_ptr s_ptr2(shmem.construct<base_class>("base_class")(),
+ base_class_allocator(shmem.get_segment_manager()),
+ base_deleter_t(shmem.get_segment_manager()));
+
+ base_shared_ptr s_ptr3(offset_ptr<derived_class>(shmem.construct<derived_class>("derived_class")()),
+ base_class_allocator(shmem.get_segment_manager()),
+ base_deleter_t(shmem.get_segment_manager()));
+
+ if(s_ptr3.get_deleter() == 0){
+ return 1;
+ }
+ //if(s_ptr3.get_allocator() == 0){
+ //return 1;
+ //}
+
+ base_shared_ptr s_ptr_empty;
+
+ if(s_ptr_empty.get_deleter() != 0){
+ return 1;
+ }
+ //if(s_ptr_empty.get_allocator() != 0){
+ //return 1;
+ //}
+ }
+ }
+ shared_memory_object::remove(process_name.c_str());
+ return 0;
+}
+
+int string_shared_ptr_vector_insertion_test()
+{
+ typedef managed_shared_memory::segment_manager segment_mngr_t;
+
+ //Allocator of chars
+ typedef allocator<char, segment_mngr_t> char_allocator_t;
+
+ //A shared memory string class
+ typedef basic_string<char, std::char_traits<char>, char_allocator_t> string_t;
+
+ //A shared memory string allocator
+ typedef allocator<string_t, segment_mngr_t> string_allocator_t;
+
+ //A deleter for shared_ptr<> that erases a shared memory string
+ typedef deleter<string_t, segment_mngr_t> string_deleter_t;
+
+ //A shared pointer that points to a shared memory string and its instantiation
+ typedef shared_ptr<string_t, string_allocator_t, string_deleter_t> string_shared_ptr_t;
+
+ //An allocator for shared pointers to a string in shared memory
+ typedef allocator<string_shared_ptr_t, segment_mngr_t> string_shared_ptr_allocator_t;
+
+ //A weak pointer that points to a shared memory string and its instantiation
+ typedef weak_ptr<string_t, string_allocator_t, string_deleter_t> string_weak_ptr_t;
+
+ //An allocator for weak pointers to a string in shared memory
+ typedef allocator<string_weak_ptr_t, segment_mngr_t > string_weak_ptr_allocator_t;
+
+ //A vector of shared pointers to strings (all in shared memory) and its instantiation
+ typedef vector<string_shared_ptr_t, string_shared_ptr_allocator_t>
+ string_shared_ptr_vector_t;
+
+ //A vector of weak pointers to strings (all in shared memory) and its instantiation
+ typedef vector<string_weak_ptr_t, string_weak_ptr_allocator_t>
+ string_weak_ptr_vector_t;
+
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ //A shared memory managed memory classes
+ shared_memory_object::remove(process_name.c_str());
+ {
+ managed_shared_memory shmem(create_only, process_name.c_str(), 20000);
+
+ {
+ const int NumElements = 100;
+ //Construct the allocator of strings
+ string_allocator_t string_allocator(shmem.get_segment_manager());
+ //Construct the allocator of a shared_ptr to string
+ string_shared_ptr_allocator_t string_shared_ptr_allocator(shmem.get_segment_manager());
+ //Construct the allocator of a shared_ptr to string
+ string_weak_ptr_allocator_t string_weak_ptr_allocator(shmem.get_segment_manager());
+ //This is a string deleter using destroy_ptr() function of the managed_shared_memory
+ string_deleter_t deleter(shmem.get_segment_manager());
+ //Create a string in shared memory, to avoid leaks with exceptions use
+ //scoped ptr until we store this pointer in the shared ptr
+ scoped_ptr<string_t, string_deleter_t> scoped_string
+ (shmem.construct<string_t>(anonymous_instance)(string_allocator), deleter);
+ //Now construct a shared pointer to a string
+ string_shared_ptr_t string_shared_ptr (scoped_string.get(),
+ string_shared_ptr_allocator,
+ deleter);
+ //Check use count is just one
+ if(!string_shared_ptr.unique()){
+ return 1;
+ }
+ //We don't need the scoped_ptr anonymous since the raw pointer is in the shared ptr
+ scoped_string.release();
+ //Now fill a shared memory vector of shared_ptrs to a string
+ string_shared_ptr_vector_t my_sharedptr_vector(string_shared_ptr_allocator);
+ my_sharedptr_vector.insert(my_sharedptr_vector.begin(), NumElements, string_shared_ptr);
+ //Insert in the middle to test movability
+ my_sharedptr_vector.insert(my_sharedptr_vector.begin() + my_sharedptr_vector.size()/2, NumElements, string_shared_ptr);
+ //Now check the shared count is the objects contained in the
+ //vector plus string_shared_ptr
+ if(string_shared_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
+ return 1;
+ }
+ //Now create a weak ptr from the shared_ptr
+ string_weak_ptr_t string_weak_ptr (string_shared_ptr);
+ //Use count should remain the same
+ if(string_weak_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
+ return 1;
+ }
+ //Now reset the local shared_ptr and check use count
+ string_shared_ptr.reset();
+ if(string_weak_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size())){
+ return 1;
+ }
+ //Now reset the local shared_ptr's use count should be zero
+ if(string_shared_ptr.use_count() != 0){
+ return 1;
+ }
+ //Now recreate the shared ptr from the weak ptr
+ //and recheck use count
+ string_shared_ptr = string_shared_ptr_t(string_weak_ptr);
+ if(string_shared_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
+ return 1;
+ }
+ //Now fill a vector of weak_ptr-s
+ string_weak_ptr_vector_t my_weakptr_vector(string_weak_ptr_allocator);
+ my_weakptr_vector.insert(my_weakptr_vector.begin(), NumElements, string_weak_ptr);
+ //The shared count should remain the same
+ if(string_shared_ptr.use_count() != static_cast<long>(my_sharedptr_vector.size()+1)){
+ return 1;
+ }
+ //So weak pointers should be fine
+ string_weak_ptr_vector_t::iterator beg = my_weakptr_vector.begin(),
+ end = my_weakptr_vector.end();
+ for(;beg != end; ++beg){
+ if(beg->expired()){
+ return 1;
+ }
+ //The shared pointer constructed from weak ptr should
+ //be the same as the original, since all weak pointer
+ //point the the same object
+ if(string_shared_ptr_t(*beg) != string_shared_ptr){
+ return 1;
+ }
+ }
+ //Now destroy all the shared ptr-s of the shared ptr vector
+ my_sharedptr_vector.clear();
+ //The only alive shared ptr should be the local one
+ if(string_shared_ptr.use_count() != 1){
+ return 1;
+ }
+ //Now we invalidate the last alive shared_ptr
+ string_shared_ptr.reset();
+ //Now all weak pointers should have expired
+ beg = my_weakptr_vector.begin();
+ end = my_weakptr_vector.end();
+ for(;beg != end; ++beg){
+ if(!beg->expired()){
+ return 1;
+ }
+ bool success = false;
+ //Now this should throw
+ try{
+ string_shared_ptr_t dummy(*beg);
+ //We should never reach here
+ return 1;
+ }
+ catch(const boost::interprocess::bad_weak_ptr &){
+ success = true;
+ }
+ if(!success){
+ return 1;
+ }
+ }
+ //Clear weak ptr vector
+ my_weakptr_vector.clear();
+ //Now lock returned shared ptr should return null
+ if(string_weak_ptr.lock().get()){
+ return 1;
+ }
+ //Reset weak_ptr
+ string_weak_ptr.reset();
+ }
+ }
+ shared_memory_object::remove(process_name.c_str());
+ return 0;
+}
+
+//
+// This part is taken from shared_ptr_basic_test.cpp
+//
+// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2006 Ion Gaztanaga
+//
+// 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)
+//
+
+static int cnt = 0;
+
+struct X
+{
+ X(){ ++cnt; }
+ // virtual destructor deliberately omitted
+ virtual ~X(){ --cnt; }
+
+ virtual int id() const
+ { return 1; }
+
+ private:
+ X(X const &);
+ X & operator= (X const &);
+};
+
+struct Y: public X
+{
+ Y(){ ++cnt; }
+ virtual ~Y(){ --cnt; }
+
+ virtual int id() const
+ { return 2; }
+
+ private:
+ Y(Y const &);
+ Y & operator= (Y const &);
+};
+
+int * get_object()
+{ ++cnt; return &cnt; }
+
+void release_object(int * p)
+{ BOOST_TEST(p == &cnt); --cnt; }
+
+template<class T, class A, class D>
+void test_is_X(shared_ptr<T, A, D> const & p)
+{
+ BOOST_TEST(p->id() == 1);
+ BOOST_TEST((*p).id() == 1);
+}
+
+template<class T, class A, class D>
+void test_is_X(weak_ptr<T, A, D> const & p)
+{
+ BOOST_TEST(p.get() != 0);
+ BOOST_TEST(p.get()->id() == 1);
+}
+
+template<class T, class A, class D>
+void test_is_Y(shared_ptr<T, A, D> const & p)
+{
+ BOOST_TEST(p->id() == 2);
+ BOOST_TEST((*p).id() == 2);
+}
+
+template<class T, class A, class D>
+void test_is_Y(weak_ptr<T, A, D> const & p)
+{
+ shared_ptr<T, A, D> q = p.lock();
+ BOOST_TEST(q.get() != 0);
+ BOOST_TEST(q->id() == 2);
+}
+
+template<class T, class T2>
+void test_eq(T const & a, T2 const & b)
+{
+ BOOST_TEST(a == b);
+ BOOST_TEST(!(a != b));
+ BOOST_TEST(!(a < b));
+ BOOST_TEST(!(b < a));
+}
+
+template<class T, class T2>
+void test_ne(T const & a, T2 const & b)
+{
+ BOOST_TEST(!(a == b));
+ BOOST_TEST(a != b);
+ BOOST_TEST(a < b || b < a);
+ BOOST_TEST(!(a < b && b < a));
+}
+
+template<class T, class U, class A, class D, class D2>
+void test_shared(weak_ptr<T, A, D> const & a, weak_ptr<U, A, D2> const & b)
+{
+ BOOST_TEST(!(a < b));
+ BOOST_TEST(!(b < a));
+}
+
+template<class T, class U, class A, class D, class D2>
+void test_nonshared(weak_ptr<T, A, D> const & a, weak_ptr<U, A, D2> const & b)
+{
+ BOOST_TEST(a < b || b < a);
+ BOOST_TEST(!(a < b && b < a));
+}
+
+template<class T, class U>
+void test_eq2(T const & a, U const & b)
+{
+ BOOST_TEST(a == b);
+ BOOST_TEST(!(a != b));
+}
+
+template<class T, class U>
+void test_ne2(T const & a, U const & b)
+{
+ BOOST_TEST(!(a == b));
+ BOOST_TEST(a != b);
+}
+
+template<class T, class A, class D>
+void test_is_zero(shared_ptr<T, A, D> const & p)
+{
+ BOOST_TEST(!p);
+ BOOST_TEST(p.get() == 0);
+}
+
+template<class T, class A, class D>
+void test_is_nonzero(shared_ptr<T, A, D> const & p)
+{
+ // p? true: false is used to test p in a boolean context.
+ // BOOST_TEST(p) is not guaranteed to test the conversion,
+ // as the macro might test !!p instead.
+ BOOST_TEST(p? true: false);
+ BOOST_TEST(p.get() != 0);
+}
+
+int basic_shared_ptr_test()
+{
+ typedef managed_shared_memory::segment_manager segment_mngr_t;
+ typedef allocator<void, segment_mngr_t> v_allocator_t;
+ typedef deleter<X, segment_mngr_t> x_deleter_t;
+ typedef deleter<Y, segment_mngr_t> y_deleter_t;
+ typedef shared_ptr<X, v_allocator_t, x_deleter_t> x_shared_ptr;
+ typedef shared_ptr<Y, v_allocator_t, y_deleter_t> y_shared_ptr;
+ typedef weak_ptr<X, v_allocator_t, x_deleter_t> x_weak_ptr;
+ typedef weak_ptr<Y, v_allocator_t, y_deleter_t> y_weak_ptr;
+
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ shared_memory_object::remove(process_name.c_str());
+ {
+ managed_shared_memory shmem(create_only, process_name.c_str(), 10000);
+ {
+ v_allocator_t v_allocator (shmem.get_segment_manager());
+ x_deleter_t x_deleter (shmem.get_segment_manager());
+ y_deleter_t y_deleter (shmem.get_segment_manager());
+
+ y_shared_ptr p (shmem.construct<Y>(anonymous_instance)(), v_allocator, y_deleter);
+ x_shared_ptr p2(shmem.construct<X>(anonymous_instance)(), v_allocator, x_deleter);
+
+ test_is_nonzero(p);
+ test_is_nonzero(p2);
+ test_is_Y(p);
+ test_is_X(p2);
+ test_ne(p, p2);
+
+ {
+ shared_ptr<X, v_allocator_t, y_deleter_t> q(p);
+ test_eq(p, q);
+ }
+
+ y_shared_ptr p3 (dynamic_pointer_cast<Y>(p));
+ shared_ptr<Y, v_allocator_t, x_deleter_t> p4 (dynamic_pointer_cast<Y>(p2));
+ test_is_nonzero(p3);
+ test_is_zero(p4);
+ BOOST_TEST(p.use_count() == 2);
+ BOOST_TEST(p2.use_count() == 1);
+ BOOST_TEST(p3.use_count() == 2);
+ test_is_Y(p3);
+ test_eq2(p, p3);
+ test_ne2(p2, p4);
+
+ shared_ptr<void, v_allocator_t, y_deleter_t> p5(p);
+
+ test_is_nonzero(p5);
+ test_eq2(p, p5);
+ BOOST_TEST(p5.use_count() == 3);
+
+ x_weak_ptr wp1(p2);
+
+ BOOST_TEST(!wp1.expired());
+ BOOST_TEST(wp1.use_count() != 0);
+
+ p.reset();
+ p2.reset();
+ p3.reset();
+ p4.reset();
+
+ test_is_zero(p);
+ test_is_zero(p2);
+ test_is_zero(p3);
+ test_is_zero(p4);
+
+ BOOST_TEST(p5.use_count() == 1);
+ BOOST_TEST(wp1.expired());
+ BOOST_TEST(wp1.use_count() == 0);
+
+ try{
+ x_shared_ptr sp1(wp1);
+ BOOST_ERROR("shared_ptr<X, A, D> sp1(wp1) failed to throw");
+ }
+ catch(boost::interprocess::bad_weak_ptr const &)
+ {}
+
+ test_is_zero(wp1.lock());
+
+ weak_ptr<X, v_allocator_t, y_deleter_t> wp2 = static_pointer_cast<X>(p5);
+
+ BOOST_TEST(wp2.use_count() == 1);
+ test_is_Y(wp2);
+ test_nonshared(wp1, wp2);
+
+ // Scoped to not affect the subsequent use_count() tests.
+ {
+ shared_ptr<X, v_allocator_t, y_deleter_t> sp2(wp2);
+ test_is_nonzero(wp2.lock());
+ }
+
+ y_weak_ptr wp3 = dynamic_pointer_cast<Y>(wp2.lock());
+
+ BOOST_TEST(wp3.use_count() == 1);
+ test_shared(wp2, wp3);
+
+ weak_ptr<X, v_allocator_t, y_deleter_t> wp4(wp3);
+
+ BOOST_TEST(wp4.use_count() == 1);
+ test_shared(wp2, wp4);
+
+ wp1 = p2;
+ test_is_zero(wp1.lock());
+
+ wp1 = p4;
+
+ x_weak_ptr wp5;
+
+ bool b1 = wp1 < wp5;
+ bool b2 = wp5 < wp1;
+
+ y_shared_ptr p6 = static_pointer_cast<Y>(p5);
+ p5.reset();
+ p6.reset();
+
+ BOOST_TEST(wp1.use_count() == 0);
+ BOOST_TEST(wp2.use_count() == 0);
+ BOOST_TEST(wp3.use_count() == 0);
+
+ // Test operator< stability for std::set< weak_ptr<> >
+ // Thanks to Joe Gottman for pointing this out
+ BOOST_TEST(b1 == (wp1 < wp5));
+ BOOST_TEST(b2 == (wp5 < wp1));
+ }
+
+ BOOST_TEST(cnt == 0);
+ }
+ shared_memory_object::remove(process_name.c_str());
+ return boost::report_errors();
+}
+
+struct alias_tester
+{
+ int v_;
+
+ explicit alias_tester( int v ): v_( v )
+ {
+ }
+
+ ~alias_tester()
+ {
+ v_ = 0;
+ }
+};
+
+void test_alias()
+{
+ typedef managed_shared_memory::segment_manager segment_mngr_t;
+ typedef allocator<void, segment_mngr_t> v_allocator_t;
+ typedef deleter<int, segment_mngr_t> int_deleter_t;
+
+ typedef shared_ptr<int, v_allocator_t, int_deleter_t> int_shared_ptr;
+ typedef shared_ptr<const int, v_allocator_t, int_deleter_t> const_int_shared_ptr;
+
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ shared_memory_object::remove(process_name.c_str());
+ {
+ managed_shared_memory shmem(create_only, process_name.c_str(), 10000);
+
+ {
+ int m = 0;
+ int_shared_ptr p;
+ int_shared_ptr p2( p, &m );
+
+ BOOST_TEST( ipcdetail::to_raw_pointer(p2.get()) == &m );
+ BOOST_TEST( p2? true: false );
+ BOOST_TEST( !!p2 );
+ BOOST_TEST( p2.use_count() == p.use_count() );
+ BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
+
+ p2.reset( p, static_cast<int*>(0) );
+
+ BOOST_TEST( p2.get() == 0 );
+
+ BOOST_TEST( p2? false: true );
+ BOOST_TEST( !p2 );
+ BOOST_TEST( p2.use_count() == p.use_count() );
+ BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
+ }
+
+ {
+ int m = 0;
+ int_shared_ptr p(make_managed_shared_ptr
+ (shmem.construct<int>(anonymous_instance)(), shmem));
+ const_int_shared_ptr p2( p, &m );
+
+ BOOST_TEST( ipcdetail::to_raw_pointer(p2.get()) == &m );
+ BOOST_TEST( p2? true: false );
+ BOOST_TEST( !!p2 );
+ BOOST_TEST( p2.use_count() == p.use_count() );
+ BOOST_TEST( !( p < p2 ) && !( p2 < p ) );
+ int_shared_ptr p_nothrow(make_managed_shared_ptr
+ (shmem.construct<int>(anonymous_instance)(), shmem, std::nothrow));
+ }
+ }
+ shared_memory_object::remove(process_name.c_str());
+}
+
+int main()
+{
+ if(0 != simple_test())
+ return 1;
+
+ if(0 != string_shared_ptr_vector_insertion_test())
+ return 1;
+
+ if(0 != basic_shared_ptr_test())
+ return 1;
+
+ test_alias();
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
+
diff --git a/src/boost/libs/interprocess/test/slist_test.cpp b/src/boost/libs/interprocess/test/slist_test.cpp
new file mode 100644
index 000000000..2f207489f
--- /dev/null
+++ b/src/boost/libs/interprocess/test/slist_test.cpp
@@ -0,0 +1,63 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/slist.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/offset_ptr.hpp>
+#include "dummy_test_allocator.hpp"
+#include "list_test.hpp"
+#include "movable_int.hpp"
+#include "emplace_test.hpp"
+
+using namespace boost::interprocess;
+
+typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
+typedef slist<int, ShmemAllocator> MyList;
+
+//typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
+//typedef slist<volatile int, ShmemVolatileAllocator> MyVolatileList;
+
+typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
+typedef slist<test::movable_int, ShmemMoveAllocator> MyMoveList;
+
+typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
+typedef slist<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveList;
+
+typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator;
+typedef slist<test::copyable_int, ShmemCopyAllocator> MyCopyList;
+
+int main ()
+{
+ if(test::list_test<managed_shared_memory, MyList, false>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyMoveList, false>())
+ return 1;
+
+ if(test::list_test<managed_shared_memory, MyCopyMoveList, false>())
+ return 1;
+
+// if(test::list_test<managed_shared_memory, MyVolatileList, false>())
+// return 1;
+
+ if(test::list_test<managed_shared_memory, MyCopyList, false>())
+ return 1;
+
+ const test::EmplaceOptions Options = (test::EmplaceOptions)
+ (test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE | test::EMPLACE_AFTER);
+
+ if(!boost::interprocess::test::test_emplace
+ < slist<test::EmplaceInt>, Options>())
+ return 1;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
+
diff --git a/src/boost/libs/interprocess/test/stable_vector_test.cpp b/src/boost/libs/interprocess/test/stable_vector_test.cpp
new file mode 100644
index 000000000..b341bc0a0
--- /dev/null
+++ b/src/boost/libs/interprocess/test/stable_vector_test.cpp
@@ -0,0 +1,72 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/stable_vector.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include "allocator_v1.hpp"
+#include "heap_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;
+
+int main()
+{
+ 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 test::heap_allocator_v1<int, managed_shared_memory::segment_manager> ShmemHeapV1Allocator;
+ typedef stable_vector<int, ShmemHeapV1Allocator> MyHeapV1Vector;
+
+ 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;
+
+ typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator;
+ typedef stable_vector<test::copyable_int, ShmemCopyAllocator> MyCopyVector;
+
+ 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, MyHeapV1Vector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyMoveVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyCopyMoveVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyCopyVector>())
+ 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>
diff --git a/src/boost/libs/interprocess/test/string_test.cpp b/src/boost/libs/interprocess/test/string_test.cpp
new file mode 100644
index 000000000..15399be83
--- /dev/null
+++ b/src/boost/libs/interprocess/test/string_test.cpp
@@ -0,0 +1,289 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/containers/string.hpp>
+#include <boost/interprocess/offset_ptr.hpp>
+#include <string>
+#include <algorithm>
+#include <cstring>
+#include <cstdio>
+#include <cstddef>
+#include "dummy_test_allocator.hpp"
+#include "check_equal_containers.hpp"
+#include "expand_bwd_test_allocator.hpp"
+#include "expand_bwd_test_template.hpp"
+#include "allocator_v1.hpp"
+#include "get_process_id_name.hpp"
+#include <new> //std::nothrow
+
+using namespace boost::interprocess;
+
+typedef test::dummy_test_allocator<char> DummyCharAllocator;
+typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString;
+typedef test::dummy_test_allocator<DummyString> DummyStringAllocator;
+typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator;
+typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString;
+typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator;
+
+struct StringEqual
+{
+ template<class Str1, class Str2>
+ bool operator ()(const Str1 &string1, const Str2 &string2) const
+ {
+ if(string1.size() != string2.size())
+ return false;
+ return std::char_traits<typename Str1::value_type>::compare
+ (string1.c_str(), string2.c_str(), (std::size_t)string1.size()) == 0;
+ }
+};
+
+//Function to check if both lists are equal
+template<class StrVector1, class StrVector2>
+bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
+{
+ StringEqual comp;
+ return std::equal(strvect1->begin(), strvect1->end(),
+ strvect2->begin(), comp);
+}
+
+template<class CharType, template<class T, class SegmentManager> class AllocatorType >
+int string_test()
+{
+ typedef std::allocator<CharType> StdAllocatorChar;
+ typedef std::basic_string<CharType, std::char_traits<CharType>, StdAllocatorChar> StdString;
+ typedef std::allocator<StdString> StdStringAllocator;
+ typedef vector<StdString, StdStringAllocator> StdStringVector;
+ typedef AllocatorType<CharType, managed_shared_memory::segment_manager> ShmemAllocatorChar;
+ typedef basic_string<CharType, std::char_traits<CharType>, ShmemAllocatorChar> ShmString;
+ typedef AllocatorType<ShmString, managed_shared_memory::segment_manager> ShmemStringAllocator;
+ typedef vector<ShmString, ShmemStringAllocator> ShmStringVector;
+
+ const int MaxSize = 100;
+
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ //Create shared memory
+ shared_memory_object::remove(process_name.c_str());
+ {
+ managed_shared_memory segment
+ (create_only,
+ process_name.c_str(),//segment name
+ 65536); //segment size in bytes
+
+ ShmemAllocatorChar shmallocator (segment.get_segment_manager());
+
+ //Initialize vector with a range or iterators and allocator
+ ShmStringVector *shmStringVect =
+ segment.construct<ShmStringVector>
+ (anonymous_instance, std::nothrow) //object name
+ (shmallocator);
+
+ StdStringVector *stdStringVect = new StdStringVector;
+
+ ShmString auxShmString (segment.get_segment_manager());
+ StdString auxStdString(StdString(auxShmString.begin(), auxShmString.end() ));
+
+ CharType buffer [20];
+
+ //First, push back
+ for(int i = 0; i < MaxSize; ++i){
+ auxShmString = "String";
+ auxStdString = "String";
+ std::sprintf(buffer, "%i", i);
+ auxShmString += buffer;
+ auxStdString += buffer;
+ shmStringVect->push_back(auxShmString);
+ stdStringVect->push_back(auxStdString);
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
+ return 1;
+ }
+
+ //Now push back moving
+ for(int i = 0; i < MaxSize; ++i){
+ auxShmString = "String";
+ auxStdString = "String";
+ std::sprintf(buffer, "%i", i);
+ auxShmString += buffer;
+ auxStdString += buffer;
+ shmStringVect->push_back(boost::move(auxShmString));
+ stdStringVect->push_back(auxStdString);
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
+ return 1;
+ }
+
+ //push front
+ for(int i = 0; i < MaxSize; ++i){
+ auxShmString = "String";
+ auxStdString = "String";
+ std::sprintf(buffer, "%i", i);
+ auxShmString += buffer;
+ auxStdString += buffer;
+ shmStringVect->insert(shmStringVect->begin(), auxShmString);
+ stdStringVect->insert(stdStringVect->begin(), auxStdString);
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
+ return 1;
+ }
+
+ //Now push front moving
+ for(int i = 0; i < MaxSize; ++i){
+ auxShmString = "String";
+ auxStdString = "String";
+ std::sprintf(buffer, "%i", i);
+ auxShmString += buffer;
+ auxStdString += buffer;
+ shmStringVect->insert(shmStringVect->begin(), boost::move(auxShmString));
+ stdStringVect->insert(stdStringVect->begin(), auxStdString);
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
+ return 1;
+ }
+
+ //Now test long and short representation swapping
+ auxShmString = "String";
+ auxStdString = "String";
+ ShmString shm_swapper(segment.get_segment_manager());
+ StdString std_swapper;
+ shm_swapper.swap(auxShmString);
+ std_swapper.swap(auxStdString);
+ if(!StringEqual()(auxShmString, auxStdString))
+ return 1;
+ if(!StringEqual()(shm_swapper, std_swapper))
+ return 1;
+
+ shm_swapper.swap(auxShmString);
+ std_swapper.swap(auxStdString);
+ if(!StringEqual()(auxShmString, auxStdString))
+ return 1;
+ if(!StringEqual()(shm_swapper, std_swapper))
+ return 1;
+
+ auxShmString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
+ auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
+ shm_swapper = ShmString (segment.get_segment_manager());
+ std_swapper = StdString ();
+ shm_swapper.swap(auxShmString);
+ std_swapper.swap(auxStdString);
+ if(!StringEqual()(auxShmString, auxStdString))
+ return 1;
+ if(!StringEqual()(shm_swapper, std_swapper))
+ return 1;
+
+ shm_swapper.swap(auxShmString);
+ std_swapper.swap(auxStdString);
+ if(!StringEqual()(auxShmString, auxStdString))
+ return 1;
+ if(!StringEqual()(shm_swapper, std_swapper))
+ return 1;
+
+ //No sort
+ std::sort(shmStringVect->begin(), shmStringVect->end());
+ std::sort(stdStringVect->begin(), stdStringVect->end());
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ const CharType prefix [] = "Prefix";
+ const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1;
+ const CharType sufix [] = "Suffix";
+
+ for(int i = 0; i < MaxSize; ++i){
+ (*shmStringVect)[i].append(sufix);
+ (*stdStringVect)[i].append(sufix);
+ (*shmStringVect)[i].insert((*shmStringVect)[i].begin(),
+ prefix, prefix + prefix_size);
+ (*stdStringVect)[i].insert((*stdStringVect)[i].begin(),
+ prefix, prefix + prefix_size);
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ for(int i = 0; i < MaxSize; ++i){
+ std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end());
+ std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ for(int i = 0; i < MaxSize; ++i){
+ std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end());
+ std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ for(int i = 0; i < MaxSize; ++i){
+ std::sort(shmStringVect->begin(), shmStringVect->end());
+ std::sort(stdStringVect->begin(), stdStringVect->end());
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ for(int i = 0; i < MaxSize; ++i){
+ (*shmStringVect)[i].replace((*shmStringVect)[i].begin(),
+ (*shmStringVect)[i].end(),
+ "String");
+ (*stdStringVect)[i].replace((*stdStringVect)[i].begin(),
+ (*stdStringVect)[i].end(),
+ "String");
+ }
+
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ shmStringVect->erase(std::unique(shmStringVect->begin(), shmStringVect->end()),
+ shmStringVect->end());
+ stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()),
+ stdStringVect->end());
+ if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
+
+ //When done, delete vector
+ segment.destroy_ptr(shmStringVect);
+ delete stdStringVect;
+ }
+ shared_memory_object::remove(process_name.c_str());
+ return 0;
+}
+
+bool test_expand_bwd()
+{
+ //Now test all back insertion possibilities
+ typedef test::expand_bwd_test_allocator<char>
+ allocator_type;
+ typedef basic_string<char, std::char_traits<char>, allocator_type>
+ string_type;
+ return test::test_all_expand_bwd<string_type>();
+}
+
+int main()
+{
+ if(string_test<char, allocator>()){
+ return 1;
+ }
+
+ if(string_test<char, test::allocator_v1>()){
+ return 1;
+ }
+
+ if(!test_expand_bwd())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/tree_test.cpp b/src/boost/libs/interprocess/test/tree_test.cpp
new file mode 100644
index 000000000..461905268
--- /dev/null
+++ b/src/boost/libs/interprocess/test/tree_test.cpp
@@ -0,0 +1,199 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <set>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/set.hpp>
+#include <boost/interprocess/containers/map.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/indexes/map_index.hpp>
+#include <boost/interprocess/indexes/iset_index.hpp>
+#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
+#include "print_container.hpp"
+#include "movable_int.hpp"
+#include "dummy_test_allocator.hpp"
+#include "set_test.hpp"
+#include "map_test.hpp"
+#include "emplace_test.hpp"
+
+///////////////////////////////////////////////////////////////////
+// //
+// This example repeats the same operations with std::set and //
+// shmem_set using the node allocator //
+// and compares the values of both containers //
+// //
+///////////////////////////////////////////////////////////////////
+
+using namespace boost::interprocess;
+
+//Customize managed_shared_memory class
+typedef basic_managed_shared_memory
+ <char,
+ simple_seq_fit<mutex_family, offset_ptr<void> >,
+ map_index
+ > my_managed_shared_memory;
+
+//We will work with narrow characters for shared memory objects
+//Alias an integer node allocator type
+typedef allocator<int, my_managed_shared_memory::segment_manager>
+ shmem_allocator_t;
+typedef allocator<std::pair<const int, int>, my_managed_shared_memory::segment_manager>
+ shmem_node_pair_allocator_t;
+typedef allocator<test::movable_int, my_managed_shared_memory::segment_manager>
+ shmem_movable_allocator_t;
+typedef allocator<std::pair<const test::movable_int, test::movable_int>, my_managed_shared_memory::segment_manager>
+ shmem_movable_node_pair_allocator_t;
+typedef allocator<test::movable_and_copyable_int, my_managed_shared_memory::segment_manager>
+ shmem_move_copy_allocator_t;
+typedef allocator<test::copyable_int, my_managed_shared_memory::segment_manager>
+ shmem_copy_allocator_t;
+typedef allocator<std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>, my_managed_shared_memory::segment_manager>
+ shmem_move_copy_node_pair_allocator_t;
+
+//Alias standard types
+typedef std::set<int> MyStdSet;
+typedef std::multiset<int> MyStdMultiSet;
+typedef std::map<int, int> MyStdMap;
+typedef std::multimap<int, int> MyStdMultiMap;
+
+//Alias non-movable types
+typedef set<int, std::less<int>, shmem_allocator_t> MyShmSet;
+typedef multiset<int, std::less<int>, shmem_allocator_t> MyShmMultiSet;
+typedef map<int, int, std::less<int>, shmem_node_pair_allocator_t> MyShmMap;
+typedef multimap<int, int, std::less<int>, shmem_node_pair_allocator_t> MyShmMultiMap;
+
+//Alias movable types
+typedef set<test::movable_int, std::less<test::movable_int>
+ ,shmem_movable_allocator_t> MyMovableShmSet;
+typedef multiset<test::movable_int,
+ std::less<test::movable_int>,
+ shmem_movable_allocator_t> MyMovableShmMultiSet;
+typedef map<test::movable_int, test::movable_int,
+ std::less<test::movable_int>,
+ shmem_movable_node_pair_allocator_t> MyMovableShmMap;
+typedef multimap<test::movable_int, test::movable_int,
+ std::less<test::movable_int>,
+ shmem_movable_node_pair_allocator_t> MyMovableShmMultiMap;
+
+typedef set<test::movable_and_copyable_int
+ ,std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_allocator_t> MyMoveCopyShmSet;
+typedef multiset<test::movable_and_copyable_int,
+ std::less<test::movable_and_copyable_int>,
+ shmem_move_copy_allocator_t> MyMoveCopyShmMultiSet;
+
+typedef set<test::copyable_int
+ ,std::less<test::copyable_int>
+ ,shmem_copy_allocator_t> MyCopyShmSet;
+typedef multiset<test::copyable_int,
+ std::less<test::copyable_int>,
+ shmem_copy_allocator_t> MyCopyShmMultiSet;
+
+
+typedef map<test::movable_and_copyable_int
+ ,test::movable_and_copyable_int
+ ,std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_node_pair_allocator_t> MyMoveCopyShmMap;
+typedef multimap<test::movable_and_copyable_int
+ ,test::movable_and_copyable_int
+ ,std::less<test::movable_and_copyable_int>
+ ,shmem_move_copy_node_pair_allocator_t> MyMoveCopyShmMultiMap;
+
+int main ()
+{
+ using namespace boost::interprocess::ipcdetail;
+
+ if(0 != test::set_test<my_managed_shared_memory
+ ,MyShmSet
+ ,MyStdSet
+ ,MyShmMultiSet
+ ,MyStdMultiSet>()){
+ return 1;
+ }
+
+ if(0 != test::set_test_copyable<my_managed_shared_memory
+ ,MyShmSet
+ ,MyStdSet
+ ,MyShmMultiSet
+ ,MyStdMultiSet>()){
+ return 1;
+ }
+
+ if(0 != test::set_test<my_managed_shared_memory
+ ,MyMovableShmSet
+ ,MyStdSet
+ ,MyMovableShmMultiSet
+ ,MyStdMultiSet>()){
+ return 1;
+ }
+
+ if(0 != test::set_test<my_managed_shared_memory
+ ,MyMoveCopyShmSet
+ ,MyStdSet
+ ,MyMoveCopyShmMultiSet
+ ,MyStdMultiSet>()){
+ return 1;
+ }
+
+ if(0 != test::set_test<my_managed_shared_memory
+ ,MyCopyShmSet
+ ,MyStdSet
+ ,MyCopyShmMultiSet
+ ,MyStdMultiSet>()){
+ return 1;
+ }
+
+ if (0 != test::map_test<my_managed_shared_memory
+ ,MyShmMap
+ ,MyStdMap
+ ,MyShmMultiMap
+ ,MyStdMultiMap>()){
+ return 1;
+ }
+
+ if(0 != test::map_test_copyable<my_managed_shared_memory
+ ,MyShmMap
+ ,MyStdMap
+ ,MyShmMultiMap
+ ,MyStdMultiMap>()){
+ return 1;
+ }
+
+// if (0 != test::map_test<my_managed_shared_memory
+// ,MyMovableShmMap
+// ,MyStdMap
+// ,MyMovableShmMultiMap
+// ,MyStdMultiMap>()){
+// return 1;
+// }
+
+ if (0 != test::map_test<my_managed_shared_memory
+ ,MyMoveCopyShmMap
+ ,MyStdMap
+ ,MyMoveCopyShmMultiMap
+ ,MyStdMultiMap>()){
+ return 1;
+ }
+
+ const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
+ if(!boost::interprocess::test::test_emplace<set<test::EmplaceInt>, SetOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<multiset<test::EmplaceInt>, SetOptions>())
+ return 1;
+ const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
+ if(!boost::interprocess::test::test_emplace<map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+ if(!boost::interprocess::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/unique_ptr_test.cpp b/src/boost/libs/interprocess/test/unique_ptr_test.cpp
new file mode 100644
index 000000000..b9e24dd2b
--- /dev/null
+++ b/src/boost/libs/interprocess/test/unique_ptr_test.cpp
@@ -0,0 +1,142 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/offset_ptr.hpp>
+#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/set.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
+#include <stdio.h>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+class MyClass
+{
+ public:
+ MyClass()
+ {}
+};
+
+typedef managed_unique_ptr<MyClass, managed_shared_memory>::type my_unique_ptr_class;
+typedef set <my_unique_ptr_class
+ ,std::less<my_unique_ptr_class>
+ ,allocator <my_unique_ptr_class
+ ,managed_shared_memory::segment_manager>
+ > MySet;
+
+typedef list<my_unique_ptr_class
+ ,allocator <my_unique_ptr_class
+ ,managed_shared_memory::segment_manager>
+ > MyList;
+
+typedef vector <my_unique_ptr_class
+ ,allocator <my_unique_ptr_class
+ ,managed_shared_memory::segment_manager>
+ > MyVector;
+
+int main()
+{
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ //Create managed shared memory
+ shared_memory_object::remove(process_name.c_str());
+ {
+ managed_shared_memory segment(create_only, process_name.c_str(), 10000);
+
+ //Create unique_ptr using dynamic allocation
+ my_unique_ptr_class my_ptr (segment.construct<MyClass>(anonymous_instance)()
+ ,segment.get_deleter<MyClass>());
+ my_unique_ptr_class my_ptr2(segment.construct<MyClass>(anonymous_instance)()
+ ,segment.get_deleter<MyClass>());
+
+ //Backup relative pointers to future tests
+ offset_ptr<MyClass> ptr1 = my_ptr.get();
+ offset_ptr<MyClass> ptr2 = my_ptr2.get();
+
+ //Test some copy constructors
+ my_unique_ptr_class my_ptr3(0, segment.get_deleter<MyClass>());
+ my_unique_ptr_class my_ptr4(boost::move(my_ptr3));
+
+ //Construct a list and fill
+ MyList list(segment.get_segment_manager());
+
+ //Insert from my_unique_ptr_class
+ list.push_front(boost::move(my_ptr));
+ list.push_back(boost::move(my_ptr2));
+
+ //Check pointers
+ assert(my_ptr.get() == 0);
+ assert(my_ptr2.get() == 0);
+ 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(boost::move(*list.begin()));
+ set.insert(boost::move(*list.rbegin()));
+
+ //Check pointers
+ assert(list.begin()->get() == 0);
+ assert(list.rbegin()->get()== 0);
+
+ //A set is ordered by std::less<my_unique_ptr_class> so
+ //be careful when comparing pointers
+ if(ptr1 < ptr2){
+ assert(set.begin()->get() == ptr1);
+ assert(set.rbegin()->get() == ptr2);
+ }
+ else{
+ assert(set.rbegin()->get() == ptr1);
+ assert(set.begin()->get() == ptr2);
+ }
+
+ //Now with vector
+ MyVector vector(segment.get_segment_manager());
+
+ //Insert from my_unique_ptr_class
+ if(ptr1 < ptr2){
+ vector.insert(vector.begin(), boost::move(*set.begin()));
+ vector.insert(vector.end(), boost::move(*set.rbegin()));
+ }
+ else{
+ vector.insert(vector.begin(), boost::move(*set.rbegin()));
+ vector.insert(vector.end(), boost::move(*set.begin()));
+ }
+
+ //Check pointers
+ assert(my_ptr.get() == 0);
+ assert(my_ptr2.get() == 0);
+ assert(vector.begin()->get() == ptr1);
+ assert(vector.rbegin()->get() == ptr2);
+
+ MyVector vector2(boost::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 = boost::move(b);
+ }
+ shared_memory_object::remove(process_name.c_str());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/unordered_test.cpp b/src/boost/libs/interprocess/test/unordered_test.cpp
new file mode 100644
index 000000000..e8995e0f7
--- /dev/null
+++ b/src/boost/libs/interprocess/test/unordered_test.cpp
@@ -0,0 +1,100 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include "get_process_id_name.hpp"
+
+//<-
+//Shield against external warnings
+#include <boost/interprocess/detail/config_external_begin.hpp>
+//->
+
+#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
+
+//<-
+#include <boost/interprocess/detail/config_external_end.hpp>
+//->
+
+#include <functional> //std::equal_to
+#include <boost/functional/hash.hpp> //boost::hash
+
+namespace bip = boost::interprocess;
+
+typedef bip::allocator<int, bip::managed_shared_memory::segment_manager> ShmemAllocator;
+typedef boost::unordered_set<int, boost::hash<int>, std::equal_to<int>, ShmemAllocator> MyUnorderedSet;
+typedef boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>, ShmemAllocator> MyUnorderedMultiSet;
+
+int main()
+{
+ //Remove any other old shared memory from the system
+ bip::shared_memory_object::remove(bip::test::get_process_id_name());
+ try {
+ bip::managed_shared_memory shm(bip::create_only, bip::test::get_process_id_name(), 65536);
+
+ //Elements to be inserted in unordered containers
+ const int elements[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ const int elements_size = sizeof(elements)/sizeof(elements[0]);
+
+ MyUnorderedSet *myset =
+ shm.construct<MyUnorderedSet>(bip::anonymous_instance)
+ ( elements_size
+ , MyUnorderedSet::hasher()
+ , MyUnorderedSet::key_equal()
+ , shm.get_allocator<int>());
+ MyUnorderedMultiSet *mymset =
+ shm.construct<MyUnorderedMultiSet>(bip::anonymous_instance)
+ ( elements_size
+ , MyUnorderedSet::hasher()
+ , MyUnorderedSet::key_equal()
+ , shm.get_allocator<int>());
+
+ //Insert elements and check sizes
+ myset->insert((&elements[0]), (&elements[elements_size]));
+ myset->insert((&elements[0]), (&elements[elements_size]));
+ mymset->insert((&elements[0]), (&elements[elements_size]));
+ mymset->insert((&elements[0]), (&elements[elements_size]));
+
+ if(myset->size() != (unsigned int)elements_size)
+ return 1;
+ if(mymset->size() != (unsigned int)elements_size*2)
+ return 1;
+
+ //Destroy elements and check sizes
+ myset->clear();
+ mymset->clear();
+
+ if(!myset->empty())
+ return 1;
+ if(!mymset->empty())
+ return 1;
+
+ //Destroy elements and check if memory has been deallocated
+ shm.destroy_ptr(myset);
+ shm.destroy_ptr(mymset);
+
+ shm.shrink_to_fit_indexes();
+ if(!shm.all_memory_deallocated())
+ return 1;
+
+ }
+ catch(...){
+ //Remove shared memory from the system
+ bip::shared_memory_object::remove(bip::test::get_process_id_name());
+ throw;
+ }
+ //Remove shared memory from the system
+ bip::shared_memory_object::remove(bip::test::get_process_id_name());
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/upgradable_mutex_test.cpp b/src/boost/libs/interprocess/test/upgradable_mutex_test.cpp
new file mode 100644
index 000000000..94bc31558
--- /dev/null
+++ b/src/boost/libs/interprocess/test/upgradable_mutex_test.cpp
@@ -0,0 +1,173 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 "mutex_test_template.hpp"
+#include "sharable_mutex_test_template.hpp"
+#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/sharable_lock.hpp>
+#include <boost/interprocess/sync/upgradable_lock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include "util.hpp"
+
+int main ()
+{
+ using namespace boost::interprocess;
+
+ test::test_all_lock<interprocess_upgradable_mutex>();
+ test::test_all_mutex<interprocess_upgradable_mutex>();
+ test::test_all_sharable_mutex<interprocess_upgradable_mutex>();
+
+ //Test lock transition
+ {
+ typedef interprocess_upgradable_mutex Mutex;
+ Mutex mut;
+ Mutex mut2;
+
+ //Conversions to scoped_lock
+ {
+ scoped_lock<Mutex> lock(mut);
+ scoped_lock<Mutex> e_lock(boost::move(lock));
+ lock.swap(e_lock);
+ }
+ {
+ scoped_lock<Mutex> lock(mut);
+ scoped_lock<Mutex> e_lock(mut2);
+ e_lock = boost::move(lock);
+ }
+ {
+ upgradable_lock<Mutex> u_lock(mut);
+ //This calls unlock_upgradable_and_lock()
+ scoped_lock<Mutex> e_lock(boost::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(boost::move(u_lock));
+ e_lock = boost::move(moved);
+ }
+ {
+ upgradable_lock<Mutex> u_lock(mut);
+ //This calls try_unlock_upgradable_and_lock()
+ scoped_lock<Mutex> e_lock(boost::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(boost::move(u_lock), try_to_lock);
+ e_lock = boost::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(boost::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(boost::move(u_lock), t);
+ e_lock = boost::move(moved);
+ }
+ {
+ sharable_lock<Mutex> s_lock(mut);
+ //This calls try_unlock_sharable_and_lock()
+ scoped_lock<Mutex> e_lock(boost::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(boost::move(s_lock), try_to_lock);
+ e_lock = boost::move(moved);
+ }
+ //Conversions to upgradable_lock
+ {
+ upgradable_lock<Mutex> lock(mut);
+ upgradable_lock<Mutex> u_lock(boost::move(lock));
+ lock.swap(u_lock);
+ }
+ {
+ upgradable_lock<Mutex> lock(mut);
+ upgradable_lock<Mutex> u_lock(mut2);
+ upgradable_lock<Mutex> moved(boost::move(lock));
+ u_lock = boost::move(moved);
+ }
+ {
+ sharable_lock<Mutex> s_lock(mut);
+ //This calls unlock_sharable_and_lock_upgradable()
+ upgradable_lock<Mutex> u_lock(boost::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(boost::move(s_lock), try_to_lock);
+ u_lock = boost::move(moved);
+ }
+ {
+ scoped_lock<Mutex> e_lock(mut);
+ //This calls unlock_and_lock_upgradable()
+ upgradable_lock<Mutex> u_lock(boost::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(boost::move(e_lock));
+ u_lock = boost::move(moved);
+ }
+ //Conversions to sharable_lock
+ {
+ sharable_lock<Mutex> lock(mut);
+ sharable_lock<Mutex> s_lock(boost::move(lock));
+ lock.swap(s_lock);
+ }
+ {
+ sharable_lock<Mutex> lock(mut);
+ sharable_lock<Mutex> s_lock(mut2);
+ sharable_lock<Mutex> moved(boost::move(lock));
+ s_lock = boost::move(moved);
+ }
+ {
+ upgradable_lock<Mutex> u_lock(mut);
+ //This calls unlock_upgradable_and_lock_sharable()
+ sharable_lock<Mutex> s_lock(boost::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(boost::move(u_lock));
+ s_lock = boost::move(moved);
+ }
+ {
+ scoped_lock<Mutex> e_lock(mut);
+ //This calls unlock_and_lock_sharable()
+ sharable_lock<Mutex> s_lock(boost::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(boost::move(e_lock));
+ s_lock = boost::move(moved);
+ }
+ }
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/user_buffer_test.cpp b/src/boost/libs/interprocess/test/user_buffer_test.cpp
new file mode 100644
index 000000000..32670af5a
--- /dev/null
+++ b/src/boost/libs/interprocess/test/user_buffer_test.cpp
@@ -0,0 +1,259 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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 <vector>
+#include <list>
+#include <iostream>
+#include <functional>
+#include <boost/interprocess/managed_external_buffer.hpp>
+#include <boost/interprocess/managed_heap_memory.hpp>
+#include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/interprocess/allocators/node_allocator.hpp>
+#include "print_container.hpp"
+
+/******************************************************************************/
+/* */
+/* This example constructs repeats the same operations with std::list, */
+/* shmem_list in user provided buffer, and shmem_list in heap memory */
+/* */
+/******************************************************************************/
+
+using namespace boost::interprocess;
+
+//We will work with wide characters for user memory objects
+//Alias <integer> node allocator type
+typedef node_allocator
+ <int, wmanaged_external_buffer::segment_manager> user_node_allocator_t;
+typedef node_allocator
+ <int, wmanaged_heap_memory::segment_manager> heap_node_allocator_t;
+
+//Alias list types
+typedef list<int, user_node_allocator_t> MyUserList;
+typedef list<int, heap_node_allocator_t> MyHeapList;
+typedef std::list<int> MyStdList;
+
+//Function to check if both lists are equal
+bool CheckEqual(MyUserList *userlist, MyStdList *stdlist, MyHeapList *heaplist)
+{
+ return std::equal(userlist->begin(), userlist->end(), stdlist->begin()) &&
+ std::equal(heaplist->begin(), heaplist->end(), stdlist->begin());
+}
+
+int main ()
+{
+ //Create the user memory who will store all objects
+ const int size_aligner = sizeof(::boost::container::dtl::max_align_t);
+ const int memsize = 65536/size_aligner*size_aligner;
+ static ::boost::container::dtl::max_align_t static_buffer[memsize/size_aligner];
+
+ {
+ //Now test move semantics
+ managed_heap_memory original(memsize);
+ managed_heap_memory move_ctor(boost::move(original));
+ managed_heap_memory move_assign;
+ move_assign = boost::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(boost::move(original));
+ managed_external_buffer move_assign;
+ move_assign = boost::move(move_ctor);
+ original.swap(move_assign);
+ }
+
+ //Named new capable user mem allocator
+ wmanaged_external_buffer user_buffer(create_only, static_buffer, memsize);
+
+ //Named new capable heap mem allocator
+ wmanaged_heap_memory heap_buffer(memsize);
+
+ //Test move semantics
+ {
+ wmanaged_external_buffer user_default;
+ wmanaged_external_buffer temp_external(boost::move(user_buffer));
+ user_default = boost::move(temp_external);
+ user_buffer = boost::move(user_default);
+ wmanaged_heap_memory heap_default;
+ wmanaged_heap_memory temp_heap(boost::move(heap_buffer));
+ heap_default = boost::move(temp_heap);
+ heap_buffer = boost::move(heap_default);
+ }
+
+ //Initialize memory
+ user_buffer.reserve_named_objects(100);
+ heap_buffer.reserve_named_objects(100);
+
+ //User memory allocator must be always be initialized
+ //since it has no default constructor
+ MyUserList *userlist = user_buffer.construct<MyUserList>(L"MyUserList")
+ (user_buffer.get_segment_manager());
+
+ MyHeapList *heaplist = heap_buffer.construct<MyHeapList>(L"MyHeapList")
+ (heap_buffer.get_segment_manager());
+
+ //Alias heap list
+ MyStdList *stdlist = new MyStdList;
+
+ int i;
+ const int max = 100;
+ for(i = 0; i < max; ++i){
+ userlist->push_back(i);
+ heaplist->push_back(i);
+ stdlist->push_back(i);
+ }
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ userlist->erase(userlist->begin()++);
+ heaplist->erase(heaplist->begin()++);
+ stdlist->erase(stdlist->begin()++);
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ userlist->pop_back();
+ heaplist->pop_back();
+ stdlist->pop_back();
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ userlist->pop_front();
+ heaplist->pop_front();
+ stdlist->pop_front();
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ std::vector<int> aux_vect;
+ #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
+ aux_vect.assign(50, -1);
+ userlist->assign(aux_vect.begin(), aux_vect.end());
+ heaplist->assign(aux_vect.begin(), aux_vect.end());
+ stdlist->assign(aux_vect.begin(), aux_vect.end());
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+ #endif
+
+ userlist->sort();
+ heaplist->sort();
+ stdlist->sort();
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
+ aux_vect.assign(50, 0);
+ #endif
+ userlist->insert(userlist->begin(), aux_vect.begin(), aux_vect.end());
+ heaplist->insert(heaplist->begin(), aux_vect.begin(), aux_vect.end());
+ stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end());
+
+ userlist->unique();
+ heaplist->unique();
+ stdlist->unique();
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ userlist->sort(std::greater<int>());
+ heaplist->sort(std::greater<int>());
+ stdlist->sort(std::greater<int>());
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ userlist->resize(userlist->size()/2);
+ heaplist->resize(heaplist->size()/2);
+ stdlist->resize(stdlist->size()/2);
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ userlist->remove(*userlist->begin());
+ heaplist->remove(*heaplist->begin());
+ stdlist->remove(*stdlist->begin());
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ for(i = 0; i < max; ++i){
+ userlist->push_back(i);
+ heaplist->push_back(i);
+ stdlist->push_back(i);
+ }
+
+ MyUserList otheruserlist(*userlist);
+ MyHeapList otherheaplist(*heaplist);
+ MyStdList otherstdlist(*stdlist);
+ userlist->splice(userlist->begin(), otheruserlist);
+ heaplist->splice(heaplist->begin(), otherheaplist);
+ stdlist->splice(stdlist->begin(), otherstdlist);
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ otheruserlist = *userlist;
+ otherheaplist = *heaplist;
+ otherstdlist = *stdlist;
+
+ userlist->sort(std::greater<int>());
+ heaplist->sort(std::greater<int>());
+ stdlist->sort(std::greater<int>());
+ otheruserlist.sort(std::greater<int>());
+ otherheaplist.sort(std::greater<int>());
+ otherstdlist.sort(std::greater<int>());
+ userlist->merge(otheruserlist, std::greater<int>());
+ heaplist->merge(otherheaplist, std::greater<int>());
+ stdlist->merge(otherstdlist, std::greater<int>());
+ if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
+
+ user_buffer.destroy<MyUserList>(L"MyUserList");
+ delete stdlist;
+
+ //Fill heap buffer until is full
+ try{
+ while(1){
+ heaplist->insert(heaplist->end(), 0);
+ }
+ }
+ catch(boost::interprocess::bad_alloc &){}
+
+ MyHeapList::size_type heap_list_size = heaplist->size();
+
+ //Copy heap buffer to another
+ const char *insert_beg = static_cast<char*>(heap_buffer.get_address());
+ const char *insert_end = insert_beg + heap_buffer.get_size();
+ std::vector<char> grow_copy (insert_beg, insert_end);
+
+ //Destroy old list
+ heap_buffer.destroy<MyHeapList>(L"MyHeapList");
+
+ //Resize copy buffer
+ grow_copy.resize(memsize*2);
+
+ //Open Interprocess machinery in the new managed external buffer
+ wmanaged_external_buffer user_buffer2(open_only, &grow_copy[0], memsize);
+
+ //Expand old Interprocess machinery to the new size
+ user_buffer2.grow(memsize);
+
+ //Get a pointer to the full list
+ userlist = user_buffer2.find<MyUserList>(L"MyHeapList").first;
+ if(!userlist){
+ return 1;
+ }
+
+ //Fill user buffer until is full
+ try{
+ while(1){
+ userlist->insert(userlist->end(), 0);
+ }
+ }
+ catch(boost::interprocess::bad_alloc &){}
+
+ MyUserList::size_type user_list_size = userlist->size();
+
+ if(user_list_size <= heap_list_size){
+ return 1;
+ }
+
+ user_buffer2.destroy_ptr(userlist);
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/util.hpp b/src/boost/libs/interprocess/test/util.hpp
new file mode 100644
index 000000000..c4e8229f2
--- /dev/null
+++ b/src/boost/libs/interprocess/test/util.hpp
@@ -0,0 +1,95 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// 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. William E. Kempf 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_TEST_UTIL_HEADER
+#define BOOST_INTERPROCESS_TEST_UTIL_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/version.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace test {
+
+inline void sleep(const boost::posix_time::ptime &xt)
+{
+ boost::interprocess::ipcdetail::thread_sleep
+ ((xt - microsec_clock::universal_time()).total_milliseconds());
+}
+
+inline boost::posix_time::ptime delay(int secs, int msecs=0, int nsecs = 0)
+{
+ (void)msecs;
+ using namespace boost::posix_time;
+ int count = static_cast<int>(double(nsecs)*
+ (double(time_duration::ticks_per_second())/double(1000000000.0)));
+ count += static_cast<int>(double(msecs)*
+ (double(time_duration::ticks_per_second())/double(1000.0)));
+ boost::posix_time::ptime cur = microsec_clock::universal_time();
+ return cur += boost::posix_time::time_duration(0, 0, secs, count);
+}
+
+inline bool in_range(const boost::posix_time::ptime& xt, int secs=1)
+{
+ boost::posix_time::ptime min = delay(-secs);
+ boost::posix_time::ptime max = delay(0);
+ return (xt > min) && (max > xt);
+}
+
+template <typename P>
+class thread_adapter
+{
+ public:
+ thread_adapter(void (*func)(void*, P &), void* param1, P &param2)
+ : func_(func), param1_(param1) ,param2_(param2){ }
+ void operator()() const { func_(param1_, param2_); }
+
+ private:
+ void (*func_)(void*, P &);
+ void* param1_;
+ P& param2_;
+};
+
+template <typename P>
+struct data
+{
+ explicit data(int id, int secs=0)
+ : m_id(id), m_value(-1), m_secs(secs), m_error(no_error)
+ {}
+ int m_id;
+ int m_value;
+ int m_secs;
+ error_code_t m_error;
+};
+
+static int shared_val = 0;
+static const int BaseSeconds = 1;
+
+} //namespace test {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_TEST_UTIL_HEADER
diff --git a/src/boost/libs/interprocess/test/vector_test.cpp b/src/boost/libs/interprocess/test/vector_test.cpp
new file mode 100644
index 000000000..6a3931c24
--- /dev/null
+++ b/src/boost/libs/interprocess/test/vector_test.cpp
@@ -0,0 +1,103 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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/managed_shared_memory.hpp>
+#include <boost/interprocess/containers/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;
+
+int test_expand_bwd()
+{
+ //Now test all back insertion possibilities
+
+ //First raw ints
+ typedef test::expand_bwd_test_allocator<int>
+ int_allocator_type;
+ typedef vector<int, int_allocator_type>
+ int_vector;
+
+ if(!test::test_all_expand_bwd<int_vector>())
+ return 1;
+
+ //Now user defined wrapped int
+ typedef test::expand_bwd_test_allocator<test::int_holder>
+ int_holder_allocator_type;
+ typedef vector<test::int_holder, int_holder_allocator_type>
+ int_holder_vector;
+
+ if(!test::test_all_expand_bwd<int_holder_vector>())
+ return 1;
+
+ //Now user defined bigger wrapped int
+ typedef test::expand_bwd_test_allocator<test::triple_int_holder>
+ triple_int_holder_allocator_type;
+
+ typedef vector<test::triple_int_holder, triple_int_holder_allocator_type>
+ triple_int_holder_vector;
+
+ if(!test::test_all_expand_bwd<triple_int_holder_vector>())
+ return 1;
+
+ return 0;
+}
+
+int main()
+{
+ typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
+ typedef vector<int, ShmemAllocator> MyVector;
+
+ 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;
+
+ typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
+ typedef vector<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveVector;
+
+ typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator;
+ typedef vector<test::copyable_int, ShmemCopyAllocator> MyCopyVector;
+
+ 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;
+
+ if(test::vector_test<managed_shared_memory, MyCopyVector>())
+ return 1;
+
+ if(test_expand_bwd())
+ return 1;
+
+ const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
+ if(!boost::interprocess::test::test_emplace
+ < vector<test::EmplaceInt>, Options>())
+ return 1;
+
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/vector_test.hpp b/src/boost/libs/interprocess/test/vector_test.hpp
new file mode 100644
index 000000000..4875b3361
--- /dev/null
+++ b/src/boost/libs/interprocess/test/vector_test.hpp
@@ -0,0 +1,254 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_TEST_VECTOR_TEST_HEADER
+#define BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER
+
+#include <boost/interprocess/detail/config_begin.hpp>
+
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include "print_container.hpp"
+#include "check_equal_containers.hpp"
+#include "movable_int.hpp"
+
+#include "get_process_id_name.hpp"
+#include "emplace_test.hpp"
+
+#include <vector>
+#include <list>
+#include <string>
+#include <iostream>
+#include <cstddef>
+
+
+namespace boost{
+namespace interprocess{
+namespace test{
+
+template<class V1, class V2>
+bool copyable_only(V1 *, V2 *, boost::interprocess::ipcdetail::false_type)
+{
+ return true;
+}
+
+//Function to check if both sets are equal
+template<class V1, class V2>
+bool copyable_only(V1 *shmvector, V2 *stdvector, boost::interprocess::ipcdetail::true_type)
+{
+ typedef typename V1::value_type IntType;
+ std::size_t size = shmvector->size();
+ stdvector->insert(stdvector->end(), 50, 1);
+ shmvector->insert(shmvector->end(), 50, IntType(1));
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
+
+ {
+ IntType move_me(1);
+ stdvector->insert(stdvector->begin()+size/2, 50, 1);
+ shmvector->insert(shmvector->begin()+size/2, 50, boost::move(move_me));
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
+ }
+ {
+ IntType move_me(2);
+ shmvector->assign(shmvector->size()/2, boost::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, boost::move(move_me));
+ stdvector->assign(stdvector->size()*3-1, 3);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
+ }
+ return true;
+}
+
+template<class ManagedSharedMemory
+ ,class MyShmVector>
+int vector_test()
+{
+ typedef std::vector<int> MyStdVector;
+ typedef typename MyShmVector::value_type IntType;
+
+ std::string process_name;
+ test::get_process_id_name(process_name);
+
+ const int Memsize = 65536;
+ const char *const shMemName = process_name.c_str();
+ const int max = 100;
+
+ {
+ //Compare several shared memory vector operations with std::vector
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ try{
+ ManagedSharedMemory segment(create_only, shMemName, Memsize);
+
+ segment.reserve_named_objects(100);
+
+ //Shared memory allocator must be always be initialized
+ //since it has no default constructor
+ MyShmVector *shmvector = segment.template construct<MyShmVector>("MyShmVector")
+ (segment.get_segment_manager());
+ MyStdVector *stdvector = new MyStdVector;
+
+ shmvector->resize(100);
+ stdvector->resize(100);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ shmvector->resize(200);
+ stdvector->resize(200);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ shmvector->resize(0);
+ stdvector->resize(0);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ for(int i = 0; i < max; ++i){
+ IntType new_int(i);
+ shmvector->insert(shmvector->end(), boost::move(new_int));
+ stdvector->insert(stdvector->end(), i);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ }
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ typename MyShmVector::iterator shmit(shmvector->begin());
+ typename MyStdVector::iterator stdit(stdvector->begin());
+ typename MyShmVector::const_iterator cshmit = shmit;
+ (void)cshmit;
+ ++shmit; ++stdit;
+ shmvector->erase(shmit);
+ stdvector->erase(stdit);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ shmvector->erase(shmvector->begin());
+ stdvector->erase(stdvector->begin());
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ {
+ //Initialize values
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType new_int(-1);
+ //BOOST_STATIC_ASSERT((::boost::move_ipcdetail::is_copy_constructible<boost::interprocess::test::movable_int>::value == false));
+ aux_vect[i] = boost::move(new_int);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+
+ shmvector->insert(shmvector->end()
+ ,::boost::make_move_iterator(&aux_vect[0])
+ ,::boost::make_move_iterator(aux_vect + 50));
+ stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ for(int i = 0, j = static_cast<int>(shmvector->size()); i < j; ++i){
+ shmvector->erase(shmvector->begin());
+ stdvector->erase(stdvector->begin());
+ }
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ }
+ {
+ IntType aux_vect[50];
+ for(int i = 0; i < 50; ++i){
+ IntType new_int(-1);
+ aux_vect[i] = boost::move(new_int);
+ }
+ int aux_vect2[50];
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ shmvector->insert(shmvector->begin()
+ ,::boost::make_move_iterator(&aux_vect[0])
+ ,::boost::make_move_iterator(aux_vect + 50));
+ stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ }
+
+ shmvector->reserve(shmvector->size()*2);
+ stdvector->reserve(stdvector->size()*2);
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ IntType push_back_this(1);
+ shmvector->push_back(boost::move(push_back_this));
+ stdvector->push_back(int(1));
+ shmvector->push_back(IntType(1));
+ stdvector->push_back(int(1));
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ if(!copyable_only(shmvector, stdvector
+ ,ipcdetail::bool_<!ipcdetail::is_same<IntType, test::movable_int>::value>())){
+ return 1;
+ }
+
+ shmvector->erase(shmvector->begin());
+ stdvector->erase(stdvector->begin());
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ for(int i = 0; i < max; ++i){
+ IntType insert_this(i);
+ shmvector->insert(shmvector->begin(), boost::move(insert_this));
+ stdvector->insert(stdvector->begin(), i);
+ shmvector->insert(shmvector->begin(), IntType(i));
+ stdvector->insert(stdvector->begin(), int(i));
+ }
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+
+ //Test insertion from list
+ {
+ std::list<int> l(50, int(1));
+ shmvector->insert(shmvector->begin(), l.begin(), l.end());
+ stdvector->insert(stdvector->begin(), l.begin(), l.end());
+ if(!test::CheckEqualContainers(shmvector, stdvector)) return 1;
+ shmvector->assign(l.begin(), l.end());
+ 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");
+ segment.shrink_to_fit_indexes();
+
+ if(!segment.all_memory_deallocated())
+ return 1;
+ }
+ catch(std::exception &ex){
+ shared_memory_object::remove(shMemName);
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+ }
+ shared_memory_object::remove(shMemName);
+ std::cout << std::endl << "Test OK!" << std::endl;
+ return 0;
+}
+
+} //namespace test{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif
diff --git a/src/boost/libs/interprocess/test/vectorstream_test.cpp b/src/boost/libs/interprocess/test/vectorstream_test.cpp
new file mode 100644
index 000000000..d20b82ac5
--- /dev/null
+++ b/src/boost/libs/interprocess/test/vectorstream_test.cpp
@@ -0,0 +1,185 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2012. 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/containers/string.hpp>
+#include <boost/interprocess/containers/vector.hpp>
+#include <boost/interprocess/streams/vectorstream.hpp>
+#include <boost/interprocess/streams/bufferstream.hpp>
+#include <sstream>
+#include <cstring>
+#include <vector>
+#include <iostream>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <stdio.h>
+
+namespace boost {
+namespace interprocess {
+
+//Force instantiations to catch compile-time errors
+typedef basic_string<char> my_string;
+typedef basic_vectorstream<my_string > my_stringstream_t;
+typedef vector<char> my_vector;
+typedef basic_vectorstream<my_vector> my_vectorstream_t;
+template class basic_vectorstream<my_string>;
+template class basic_vectorstream<std::vector<char> >;
+
+}}
+
+using namespace boost::interprocess;
+
+static int vectorstream_test()
+{
+ { //Test high watermarking initialization
+ my_stringstream_t my_stringstream;
+
+ if(my_stringstream.tellg() != std::streampos(0)){
+ return 1;
+ }
+ if(my_stringstream.tellp() != std::streampos(0)){
+ return 1;
+ }
+
+ int a (0);
+ my_stringstream << 11;
+ my_stringstream >> a;
+ if(a != 11)
+ return 1;
+ }
+ { //Test high watermarking initialization
+ my_vectorstream_t my_stringstream;
+ int a (0);
+ my_stringstream << 13;
+ my_stringstream >> a;
+ if(a != 13)
+ return 1;
+ }
+
+ //Pre-reserved string
+ {
+ my_stringstream_t my_stringstream;
+ std::stringstream std_stringstream;
+ std::string str1, str2, str3("testline:");
+ int number1, number2;
+
+ my_stringstream.reserve(10000);
+ for(int i = 0; i < 100; ++i){
+ my_stringstream << "testline: " << i << std::endl;
+ std_stringstream << "testline: " << i << std::endl;
+ }
+
+ if(std::strcmp(my_stringstream.vector().c_str(), std_stringstream.str().c_str()) != 0){
+ return 1;
+ }
+
+ for(int i = 0; i < 100; ++i){
+ my_stringstream >> str1 >> number1;
+ std_stringstream >> str2 >> number2;
+ if((str1 != str2) || (str1 != str3)){
+ assert(0); return 1;
+ }
+ if((number1 != number2) || (number1 != i)){
+ assert(0); return 1;
+ }
+ }
+ }
+ //Pre-reserved vector
+ {
+ basic_vectorstream<std::vector<char> > my_vectorstream;
+ std::vector<char> myvector;
+ std::stringstream std_stringstream;
+ std::string str1, str2, str3("testline:");
+ int number1, number2;
+
+ my_vectorstream.reserve(10000);
+ for(int i = 0; i < 100; ++i){
+ my_vectorstream << "testline: " << i << std::endl;
+ std_stringstream << "testline: " << i << std::endl;
+ }
+ //Add final null to form a c string
+ myvector.push_back(0);
+ if(std::strcmp(&(my_vectorstream.vector()[0]), std_stringstream.str().c_str()) != 0){
+ return 1;
+ }
+ myvector.pop_back();
+ for(int i = 0; i < 100; ++i){
+ my_vectorstream >> str1 >> number1;
+ std_stringstream >> str2 >> number2;
+ if((str1 != str2) || (str1 != str3)){
+ assert(0); return 1;
+ }
+ if((number1 != number2) || (number1 != i)){
+ assert(0); return 1;
+ }
+ }
+ }
+
+ //No pre-reserved or pre-reserved string
+ {
+ my_stringstream_t my_stringstream;
+ std::stringstream std_stringstream;
+ std::string str1, str2, str3("testline:");
+ int number1, number2;
+
+ for(int i = 0; i < 100; ++i){
+ my_stringstream << "testline: " << i << std::endl;
+ std_stringstream << "testline: " << i << std::endl;
+ }
+ if(std::strcmp(my_stringstream.vector().c_str(), std_stringstream.str().c_str()) != 0){
+ assert(0); return 1;
+ }
+ for(int i = 0; i < 100; ++i){
+ my_stringstream >> str1 >> number1;
+ std_stringstream >> str2 >> number2;
+ if((str1 != str2) || (str1 != str3)){
+ assert(0); return 1;
+ }
+ if((number1 != number2) || (number1 != i)){
+ assert(0); return 1;
+ }
+ }
+ }
+
+ //Test seek
+ {
+ my_stringstream_t my_stringstream;
+ my_stringstream << "ABCDEFGHIJKLM";
+ my_stringstream.seekp(0);
+ my_stringstream << "PQRST";
+ string s("PQRSTFGHIJKLM");
+ if(s != my_stringstream.vector()){
+ return 1;
+ }
+ my_stringstream.seekp(0, std::ios_base::end);
+ my_stringstream << "NOPQRST";
+ s ="PQRSTFGHIJKLMNOPQRST";
+ if(s != my_stringstream.vector()){
+ return 1;
+ }
+ int size = static_cast<int>(my_stringstream.vector().size());
+ my_stringstream.seekp(-size, std::ios_base::cur);
+ my_stringstream << "ABCDE";
+ s ="ABCDEFGHIJKLMNOPQRST";
+ if(s != my_stringstream.vector()){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main ()
+{
+ if(vectorstream_test()){
+ return 1;
+ }
+ return 0;
+}
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/windows_shared_dir_func.cpp b/src/boost/libs/interprocess/test/windows_shared_dir_func.cpp
new file mode 100644
index 000000000..135f2460b
--- /dev/null
+++ b/src/boost/libs/interprocess/test/windows_shared_dir_func.cpp
@@ -0,0 +1,84 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_INTERPROCESS_WINDOWS
+
+#define BOOST_INTERPROCESS_WINDOWS
+
+//Force user-defined get_shared_dir
+#define BOOST_INTERPROCESS_SHARED_DIR_FUNC
+#include <boost/interprocess/detail/shared_dir_helpers.hpp>
+#include <string>
+
+#include "get_process_id_name.hpp"
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+static bool dir_created = false;
+
+inline void get_shared_dir(std::string &shared_dir)
+{
+ shared_dir = boost::interprocess::ipcdetail::get_temporary_path();
+ shared_dir += "/boostipctest_";
+ shared_dir += boost::interprocess::test::get_process_id_name();
+ if(!dir_created)
+ ipcdetail::create_directory(shared_dir.c_str());
+ dir_created = true;
+}
+
+}}} //namespace boost::interprocess::ipcdetail
+
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <iostream>
+
+int main ()
+{
+ using namespace boost::interprocess;
+ const char *const shm_name = "test_shm";
+ std::string shared_dir;
+ ipcdetail::get_shared_dir(shared_dir);
+
+ std::string shm_path(shared_dir);
+ shm_path += shm_name;
+
+ int ret = 0;
+ shared_memory_object::remove(shm_name);
+ {
+ shared_memory_object shm(create_only, shm_name, read_write);
+
+ shm_path += shm_name;
+ int ret = ipcdetail::invalid_file() == ipcdetail::open_existing_file(shm_path.c_str(), read_only) ?
+ 1 : 0;
+ if(ret)
+ {
+ std::cerr << "Error opening user get_shared_dir()/shm file" << std::endl;
+ }
+ }
+ shared_memory_object::remove(shm_name);
+ ipcdetail::remove_directory(shared_dir.c_str());
+
+ return ret;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif //#ifdef BOOST_INTERPROCESS_WINDOWS
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/windows_shared_memory_mapping_test.cpp b/src/boost/libs/interprocess/test/windows_shared_memory_mapping_test.cpp
new file mode 100644
index 000000000..582b2ba35
--- /dev/null
+++ b/src/boost/libs/interprocess/test/windows_shared_memory_mapping_test.cpp
@@ -0,0 +1,138 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_INTERPROCESS_WINDOWS
+
+#include <fstream>
+#include <iostream>
+#include <boost/interprocess/windows_shared_memory.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <string>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+int main ()
+{
+ try{
+ const char *names[2] = { test::get_process_id_name(), 0 };
+ for(unsigned int i_name = 0; i_name < sizeof(names)/sizeof(names[0]); ++i_name)
+ {
+ const std::size_t FileSize = 99999*2;
+ //Create a file mapping
+ windows_shared_memory mapping
+ (create_only, names[i_name], read_write, FileSize);
+ if(static_cast<std::size_t>(mapping.get_size()) < FileSize)
+ return 1;
+ {
+
+ //Create two mapped regions, one half of the file each
+ mapped_region region (mapping
+ ,read_write
+ ,0
+ ,FileSize/2
+ ,0);
+
+ mapped_region region2(mapping
+ ,read_write
+ ,FileSize/2
+ ,FileSize - FileSize/2
+ ,0);
+
+ //Fill two regions with a pattern
+ unsigned char *filler = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+
+ filler = static_cast<unsigned char*>(region2.get_address());
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+ if(!region.flush(0, 0, false)){
+ return 1;
+ }
+
+ if(!region2.flush(0, 0, true)){
+ return 1;
+ }
+ }
+
+ //See if the pattern is correct in the file using two mapped regions
+ {
+ mapped_region region (mapping, read_only, 0, FileSize/2, 0);
+ mapped_region region2(mapping, read_only, FileSize/2, FileSize - FileSize/2, 0);
+
+ unsigned char *checker = static_cast<unsigned char*>(region.get_address());
+ //Check pattern
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+
+ //Check second half
+ checker = static_cast<unsigned char *>(region2.get_address());
+
+ //Check pattern
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+
+ //Now check the pattern mapping a single read only mapped_region
+ {
+ //Create a single regions, mapping all the file
+ mapped_region region (mapping, read_only);
+
+ //Check pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ catch(std::exception &exc){
+ //shared_memory_object::remove(test::get_process_id_name());
+ std::cout << "Unhandled exception: " << exc.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/windows_shared_memory_test.cpp b/src/boost/libs/interprocess/test/windows_shared_memory_test.cpp
new file mode 100644
index 000000000..6a235bb1c
--- /dev/null
+++ b/src/boost/libs/interprocess/test/windows_shared_memory_test.cpp
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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_INTERPROCESS_WINDOWS
+
+#include <boost/interprocess/windows_shared_memory.hpp>
+#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include "named_creation_template.hpp"
+#include <cstring> //for strcmp, memset
+#include <iostream> //for cout
+#include <string> //for string
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+static const char *name_initialization_routine()
+{
+ static std::string process_name;
+ test::get_process_id_name(process_name);
+ return process_name.c_str();
+}
+
+static const std::size_t ShmSize = 1000;
+typedef ipcdetail::managed_open_or_create_impl
+ <windows_shared_memory, 0, false, 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 windows_shared_memory_t
+{
+ public:
+ shared_memory_creation_test_wrapper(create_only_t)
+ : windows_shared_memory_t(create_only, name_initialization_routine(), ShmSize, read_write, 0, permissions())
+ {}
+
+ shared_memory_creation_test_wrapper(open_only_t)
+ : windows_shared_memory_t(open_only, name_initialization_routine(), read_write, 0)
+ {}
+
+ shared_memory_creation_test_wrapper(open_or_create_t)
+ : windows_shared_memory_t(open_or_create, name_initialization_routine(), ShmSize, read_write, 0, permissions())
+ {}
+};
+
+
+int main ()
+{
+ try{
+ test::test_named_creation<shared_memory_creation_test_wrapper>();
+ }
+ catch(std::exception &ex){
+ std::cout << ex.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif //#ifdef BOOST_INTERPROCESS_WINDOWS
+
+#include <boost/interprocess/detail/config_end.hpp>
diff --git a/src/boost/libs/interprocess/test/xsi_shared_memory_mapping_test.cpp b/src/boost/libs/interprocess/test/xsi_shared_memory_mapping_test.cpp
new file mode 100644
index 000000000..24d0df083
--- /dev/null
+++ b/src/boost/libs/interprocess/test/xsi_shared_memory_mapping_test.cpp
@@ -0,0 +1,139 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2012. 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>
+
+#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
+
+#include <fstream>
+#include <iostream>
+#include <boost/interprocess/xsi_shared_memory.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/file_mapping.hpp>
+#include <boost/interprocess/detail/file_wrapper.hpp>
+#include <string>
+#include <iostream>
+#include "get_process_id_name.hpp"
+
+using namespace boost::interprocess;
+
+void remove_shared_memory(const xsi_key &key)
+{
+ try{
+ xsi_shared_memory xsi(open_only, key);
+ xsi_shared_memory::remove(xsi.get_shmid());
+ }
+ catch(interprocess_exception &e){
+ if(e.get_error_code() != not_found_error)
+ throw;
+ }
+}
+
+class xsi_shared_memory_remover
+{
+ public:
+ xsi_shared_memory_remover(xsi_shared_memory &xsi_shm)
+ : xsi_shm_(xsi_shm)
+ {}
+
+ ~xsi_shared_memory_remover()
+ { xsi_shared_memory::remove(xsi_shm_.get_shmid()); }
+ private:
+ xsi_shared_memory & xsi_shm_;
+};
+
+inline std::string get_filename()
+{
+ std::string ret (ipcdetail::get_temporary_path());
+ ret += "/";
+ ret += test::get_process_id_name();
+ return ret;
+}
+
+int main ()
+{
+ std::string filename(get_filename());
+ const char *names[2] = { filename.c_str(), 0 };
+
+ file_mapping::remove(names[0]);
+ { ipcdetail::file_wrapper(create_only, names[0], read_write); }
+ xsi_key key(names[0], 1);
+ file_mapping::remove(names[0]);
+ remove_shared_memory(key);
+
+ unsigned int i;
+ try{
+ for(i = 0; i < sizeof(names)/sizeof(names[0]); ++i)
+ {
+ const std::size_t FileSize = 99999*2;
+ //Create a file mapping
+ xsi_shared_memory mapping (create_only, names[i] ? key : xsi_key(), FileSize);
+ xsi_shared_memory_remover rem(mapping);
+ try{
+ {
+ //Partial mapping should fail fox XSI shared memory
+ bool thrown = false;
+ try{
+ mapped_region region2(mapping, read_write, FileSize/2, FileSize - FileSize/2, 0);
+ }
+ catch(...){
+ thrown = true;
+ }
+ if(thrown == false){
+ return 1;
+ }
+ //Create a mapped region
+ mapped_region region (mapping, read_write, 0, FileSize, 0);
+
+ //Fill two regions with a pattern
+ unsigned char *filler = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0; i < FileSize; ++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
+ }
+
+ //Now check the pattern mapping a single read only mapped_region
+ {
+ //Create a single region, mapping all the file
+ mapped_region region (mapping, read_only);
+
+ //Check pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0; i < FileSize; ++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
+ }
+ catch(std::exception &exc){
+ std::cout << "Unhandled exception: " << exc.what() << std::endl;
+ return 1;
+ }
+ }
+ }
+ catch(std::exception &exc){
+ std::cout << "Unhandled exception: " << exc.what() << std::endl;
+ return 1;
+ }
+ return 0;
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+
+#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+
+#include <boost/interprocess/detail/config_end.hpp>