|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r78115 - in branches/release: boost/container boost/container/allocator boost/container/detail boost/interprocess boost/interprocess/detail boost/interprocess/smart_ptr boost/interprocess/smart_ptr/detail boost/interprocess/sync boost/interprocess/sync/detail boost/interprocess/sync/shm boost/interprocess/sync/windows boost/intrusive boost/intrusive/detail boost/move libs/container libs/container/doc libs/container/example libs/container/proj libs/container/proj/vc7ide libs/container/test libs/interprocess libs/interprocess/doc libs/interprocess/proj/vc7ide libs/interprocess/test libs/intrusive
From: igaztanaga_at_[hidden]
Date: 2012-04-21 16:36:20
Author: igaztanaga
Date: 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
New Revision: 78115
URL: http://svn.boost.org/trac/boost/changeset/78115
Log:
Merged from trunk
Added:
branches/release/boost/container/allocator_traits.hpp
- copied unchanged from r78114, /trunk/boost/container/allocator_traits.hpp
branches/release/boost/container/detail/memory_util.hpp
- copied unchanged from r78114, /trunk/boost/container/detail/memory_util.hpp
branches/release/boost/container/scoped_allocator.hpp
- copied unchanged from r78114, /trunk/boost/container/scoped_allocator.hpp
branches/release/boost/interprocess/detail/file_locking_helpers.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/detail/file_locking_helpers.hpp
branches/release/boost/interprocess/detail/intermodule_singleton_common.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/detail/intermodule_singleton_common.hpp
branches/release/boost/interprocess/detail/managed_global_memory.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/detail/managed_global_memory.hpp
branches/release/boost/interprocess/detail/portable_intermodule_singleton.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/detail/portable_intermodule_singleton.hpp
branches/release/boost/interprocess/detail/windows_intermodule_singleton.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/detail/windows_intermodule_singleton.hpp
branches/release/boost/interprocess/sync/detail/
- copied from r78114, /trunk/boost/interprocess/sync/detail/
branches/release/boost/interprocess/sync/windows/named_condition.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/named_condition.hpp
branches/release/boost/interprocess/sync/windows/named_mutex.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/named_mutex.hpp
branches/release/boost/interprocess/sync/windows/named_recursive_mutex.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/named_recursive_mutex.hpp
branches/release/boost/interprocess/sync/windows/named_semaphore.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/named_semaphore.hpp
branches/release/boost/interprocess/sync/windows/named_sync.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/named_sync.hpp
branches/release/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
branches/release/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
- copied unchanged from r78114, /trunk/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
branches/release/libs/container/proj/vc7ide/scoped_allocator_adaptor.vcproj
- copied unchanged from r78114, /trunk/libs/container/proj/vc7ide/scoped_allocator_adaptor.vcproj
branches/release/libs/container/proj/vc7ide/scoped_allocator_usage_test.vcproj
- copied unchanged from r78114, /trunk/libs/container/proj/vc7ide/scoped_allocator_usage_test.vcproj
branches/release/libs/container/test/scoped_allocator_adaptor_test.cpp
- copied unchanged from r78114, /trunk/libs/container/test/scoped_allocator_adaptor_test.cpp
branches/release/libs/container/test/scoped_allocator_usage_test.cpp
- copied unchanged from r78114, /trunk/libs/container/test/scoped_allocator_usage_test.cpp
Removed:
branches/release/boost/container/allocator/
Properties modified:
branches/release/boost/interprocess/ (props changed)
branches/release/boost/intrusive/ (props changed)
branches/release/libs/interprocess/ (props changed)
branches/release/libs/intrusive/ (props changed)
Text files modified:
branches/release/boost/container/container_fwd.hpp | 20
branches/release/boost/container/deque.hpp | 44 +
branches/release/boost/container/detail/adaptive_node_pool_impl.hpp | 2
branches/release/boost/container/detail/advanced_insert_int.hpp | 131 ++-
branches/release/boost/container/detail/algorithms.hpp | 2
branches/release/boost/container/detail/allocation_type.hpp | 2
branches/release/boost/container/detail/config_begin.hpp | 3
branches/release/boost/container/detail/config_end.hpp | 2
branches/release/boost/container/detail/destroyers.hpp | 35 +
branches/release/boost/container/detail/flat_tree.hpp | 74 ++
branches/release/boost/container/detail/function_detector.hpp | 2
branches/release/boost/container/detail/iterators.hpp | 14
branches/release/boost/container/detail/math_functions.hpp | 2
branches/release/boost/container/detail/mpl.hpp | 2
branches/release/boost/container/detail/multiallocation_chain.hpp | 2
branches/release/boost/container/detail/node_alloc_holder.hpp | 59 -
branches/release/boost/container/detail/node_pool_impl.hpp | 2
branches/release/boost/container/detail/pair.hpp | 115 ++-
branches/release/boost/container/detail/pool_common.hpp | 2
branches/release/boost/container/detail/preprocessor.hpp | 33
branches/release/boost/container/detail/stored_ref.hpp | 2
branches/release/boost/container/detail/transform_iterator.hpp | 2
branches/release/boost/container/detail/tree.hpp | 120 +--
branches/release/boost/container/detail/type_traits.hpp | 9
branches/release/boost/container/detail/utilities.hpp | 15
branches/release/boost/container/detail/value_init.hpp | 2
branches/release/boost/container/detail/variadic_templates_tools.hpp | 2
branches/release/boost/container/detail/version_type.hpp | 2
branches/release/boost/container/detail/workaround.hpp | 7
branches/release/boost/container/flat_map.hpp | 76 ++
branches/release/boost/container/flat_set.hpp | 84 ++
branches/release/boost/container/list.hpp | 55 +
branches/release/boost/container/map.hpp | 72 ++
branches/release/boost/container/set.hpp | 40 +
branches/release/boost/container/slist.hpp | 56 +
branches/release/boost/container/stable_vector.hpp | 166 +++--
branches/release/boost/container/string.hpp | 34 +
branches/release/boost/container/vector.hpp | 179 ++++++
branches/release/boost/interprocess/detail/atomic.hpp | 169 ++---
branches/release/boost/interprocess/detail/config_begin.hpp | 1
branches/release/boost/interprocess/detail/intermodule_singleton.hpp | 1142 ---------------------------------------
branches/release/boost/interprocess/detail/os_file_functions.hpp | 12
branches/release/boost/interprocess/detail/pointer_type.hpp | 2
branches/release/boost/interprocess/detail/preprocessor.hpp | 30
branches/release/boost/interprocess/detail/robust_emulation.hpp | 4
branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp | 163 ++--
branches/release/boost/interprocess/detail/win32_api.hpp | 29
branches/release/boost/interprocess/detail/workaround.hpp | 125 +--
branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp | 2
branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp | 2
branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp | 7
branches/release/boost/interprocess/sync/interprocess_condition.hpp | 6
branches/release/boost/interprocess/sync/interprocess_mutex.hpp | 6
branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 6
branches/release/boost/interprocess/sync/interprocess_semaphore.hpp | 6
branches/release/boost/interprocess/sync/named_condition.hpp | 16
branches/release/boost/interprocess/sync/named_mutex.hpp | 27
branches/release/boost/interprocess/sync/named_recursive_mutex.hpp | 14
branches/release/boost/interprocess/sync/named_semaphore.hpp | 11
branches/release/boost/interprocess/sync/shm/named_condition.hpp | 11
branches/release/boost/interprocess/sync/windows/condition.hpp | 311 +---------
branches/release/boost/interprocess/sync/windows/mutex.hpp | 55 -
branches/release/boost/interprocess/sync/windows/semaphore.hpp | 57 -
branches/release/boost/interprocess/sync/windows/sync_utils.hpp | 39
branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp | 8
branches/release/boost/intrusive/detail/memory_util.hpp | 7
branches/release/boost/move/move.hpp | 36 +
branches/release/libs/container/doc/Jamfile.v2 | 4
branches/release/libs/container/doc/container.qbk | 64 +
branches/release/libs/container/example/doc_emplace.cpp | 2
branches/release/libs/container/example/doc_move_containers.cpp | 2
branches/release/libs/container/example/doc_recursive_containers.cpp | 2
branches/release/libs/container/example/doc_type_erasure.cpp | 2
branches/release/libs/container/index.html | 2
branches/release/libs/container/proj/to-do.txt | 17
branches/release/libs/container/proj/vc7ide/container.sln | 16
branches/release/libs/container/proj/vc7ide/container.vcproj | 22
branches/release/libs/container/test/allocator_traits_test.cpp | 4
branches/release/libs/container/test/deque_test.cpp | 2
branches/release/libs/container/test/dummy_test_allocator.hpp | 6
branches/release/libs/container/test/expand_bwd_test_allocator.hpp | 6
branches/release/libs/container/test/flat_tree_test.cpp | 8
branches/release/libs/container/test/heap_allocator_v1.hpp | 2
branches/release/libs/container/test/list_test.cpp | 2
branches/release/libs/container/test/map_test.hpp | 15
branches/release/libs/container/test/pair_test.cpp | 2
branches/release/libs/container/test/print_container.hpp | 2
branches/release/libs/container/test/set_test.hpp | 2
branches/release/libs/container/test/slist_test.cpp | 2
branches/release/libs/container/test/stable_vector_test.cpp | 2
branches/release/libs/container/test/string_test.cpp | 2
branches/release/libs/container/test/tree_test.cpp | 4
branches/release/libs/container/test/util.hpp | 2
branches/release/libs/container/test/vector_test.cpp | 25
branches/release/libs/container/test/vector_test.hpp | 2
branches/release/libs/interprocess/doc/interprocess.qbk | 9
branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj | 50 +
branches/release/libs/interprocess/test/heap_allocator_v1.hpp | 10
branches/release/libs/interprocess/test/named_semaphore_test.cpp | 25
branches/release/libs/interprocess/test/vectorstream_test.cpp | 7
100 files changed, 1750 insertions(+), 2349 deletions(-)
Modified: branches/release/boost/container/container_fwd.hpp
==============================================================================
--- branches/release/boost/container/container_fwd.hpp (original)
+++ branches/release/boost/container/container_fwd.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -132,26 +132,22 @@
//! Type used to tag that the input range is
//! guaranteed to be ordered
-struct ordered_range_impl_t {};
+struct ordered_range_t
+{};
//! Type used to tag that the input range is
//! guaranteed to be ordered and unique
-struct ordered_unique_range_impl_t{};
-
-/// @cond
-
-typedef ordered_range_impl_t * ordered_range_t;
-typedef ordered_unique_range_impl_t *ordered_unique_range_t;
-
-/// @endcond
+struct ordered_unique_range_t
+ : public ordered_range_t
+{};
//! Value used to tag that the input range is
//! guaranteed to be ordered
-static const ordered_range_t ordered_range = 0;
+static const ordered_range_t ordered_range = ordered_range_t();
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
-static const ordered_unique_range_t ordered_unique_range = 0;
+static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
/// @cond
Modified: branches/release/boost/container/deque.hpp
==============================================================================
--- branches/release/boost/container/deque.hpp (original)
+++ branches/release/boost/container/deque.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -44,7 +44,7 @@
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <cstddef>
#include <iterator>
@@ -896,6 +896,46 @@
: Base(boost::move(static_cast<Base&>(x)))
{ this->swap_members(x); }
+ //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocation
+ //! throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ deque(const deque& x, const allocator_type &a)
+ : Base(a)
+ {
+ if(x.size()){
+ this->priv_initialize_map(x.size());
+ boost::container::uninitialized_copy_alloc
+ (this->alloc(), x.begin(), x.end(), this->members_.m_start);
+ }
+ }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves mx's resources to *this if a == allocator_type().
+ //! Otherwise copies values from x to *this.
+ //!
+ //! <b>Throws</b>: If allocation or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
+ deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
+ : Base(a)
+ {
+ if(mx.alloc() == a){
+ this->swap_members(mx);
+ }
+ else{
+ if(mx.size()){
+ this->priv_initialize_map(mx.size());
+ boost::container::uninitialized_copy_alloc
+ (this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
+ }
+ }
+ }
+
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the deque.
//!
Modified: branches/release/boost/container/detail/adaptive_node_pool_impl.hpp
==============================================================================
--- branches/release/boost/container/detail/adaptive_node_pool_impl.hpp (original)
+++ branches/release/boost/container/detail/adaptive_node_pool_impl.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/advanced_insert_int.hpp
==============================================================================
--- branches/release/boost/container/detail/advanced_insert_int.hpp (original)
+++ branches/release/boost/container/detail/advanced_insert_int.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (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)
//
@@ -17,7 +17,9 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/aligned_storage.hpp>
#include <boost/move/move.hpp>
#include <iterator> //std::iterator_traits
#include <boost/assert.hpp>
@@ -41,7 +43,6 @@
struct advanced_insert_aux_proxy
: public advanced_insert_aux_int<Iterator>
{
- typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
@@ -54,36 +55,36 @@
{}
virtual void copy_remaining_to(Iterator p)
- { ::boost::copy_or_move(first_, last_, p); }
+ { ::boost::copy_or_move(this->first_, this->last_, p); }
virtual void uninitialized_copy_remaining_to(Iterator p)
- { ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p); }
+ { ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
- FwdIt mid = first_;
+ FwdIt mid = this->first_;
std::advance(mid, division_count);
if(first_n){
- ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
- first_ = mid;
+ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
+ this->first_ = mid;
}
else{
- ::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
- last_ = mid;
+ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
+ this->last_ = mid;
}
}
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
- FwdIt mid = first_;
+ FwdIt mid = this->first_;
std::advance(mid, division_count);
if(first_n){
- ::boost::copy_or_move(first_, mid, pos);
- first_ = mid;
+ ::boost::copy_or_move(this->first_, mid, pos);
+ this->first_ = mid;
}
else{
- ::boost::copy_or_move(mid, last_, pos);
- last_ = mid;
+ ::boost::copy_or_move(mid, this->last_, pos);
+ this->last_ = mid;
}
}
A &a_;
@@ -95,7 +96,7 @@
struct default_construct_aux_proxy
: public advanced_insert_aux_int<Iterator>
{
- typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef ::boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
@@ -109,11 +110,11 @@
virtual void copy_remaining_to(Iterator)
{ //This should never be called with any count
- BOOST_ASSERT(count_ == 0);
+ BOOST_ASSERT(this->count_ == 0);
}
virtual void uninitialized_copy_remaining_to(Iterator p)
- { this->priv_uninitialized_copy(p, count_); }
+ { this->priv_uninitialized_copy(p, this->count_); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
@@ -122,22 +123,22 @@
new_count = division_count;
}
else{
- BOOST_ASSERT(difference_type(count_)>= division_count);
- new_count = count_ - division_count;
+ BOOST_ASSERT(difference_type(this->count_)>= division_count);
+ new_count = this->count_ - division_count;
}
this->priv_uninitialized_copy(pos, new_count);
}
virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
{
- BOOST_ASSERT(count_ == 0);
+ BOOST_ASSERT(this->count_ == 0);
size_type new_count;
if(first_n){
new_count = division_count;
}
else{
- BOOST_ASSERT(difference_type(count_)>= division_count);
- new_count = count_ - division_count;
+ BOOST_ASSERT(difference_type(this->count_)>= division_count);
+ new_count = this->count_ - division_count;
}
//This function should never called with a count different to zero
BOOST_ASSERT(new_count == 0);
@@ -147,21 +148,21 @@
private:
void priv_uninitialized_copy(Iterator p, const size_type n)
{
- BOOST_ASSERT(n <= count_);
+ BOOST_ASSERT(n <= this->count_);
Iterator orig_p = p;
size_type i = 0;
try{
for(; i < n; ++i, ++p){
- alloc_traits::construct(a_, container_detail::to_raw_pointer(&*p));
+ alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
}
}
catch(...){
while(i--){
- alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
+ alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
}
throw;
}
- count_ -= n;
+ this->count_ -= n;
}
A &a_;
size_type count_;
@@ -223,13 +224,13 @@
{
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!used_){
- alloc_traits::construct( a_
+ if(!this->used_){
+ alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail::
- stored_ref<Args>::forward(get<IdxPack>(args_))...
+ stored_ref<Args>::forward(get<IdxPack>(this->args_))...
);
- used_ = true;
+ this->used_ = true;
}
}
}
@@ -237,13 +238,13 @@
template<int ...IdxPack>
void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{
- if(!used_){
- alloc_traits::construct( a_
+ if(!this->used_){
+ alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail::
- stored_ref<Args>::forward(get<IdxPack>(args_))...
+ stored_ref<Args>::forward(get<IdxPack>(this->args_))...
);
- used_ = true;
+ this->used_ = true;
}
}
@@ -260,12 +261,13 @@
: public advanced_insert_aux_non_movable_emplace<A, Iterator, Args...>
{
typedef advanced_insert_aux_non_movable_emplace<A, Iterator, Args...> base_t;
+ typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::index_tuple_t index_tuple_t;
explicit advanced_insert_aux_emplace(A &a, Args&&... args)
- : base_t(a, boost::forward<Args>(args)...)
+ : base_t(a, ::boost::forward<Args>(args)...)
{}
~advanced_insert_aux_emplace()
@@ -283,8 +285,13 @@
void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!this->used_){
- *p = boost::move(value_type (
- ::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
+ alloc_traits::construct(this->a_, vp,
+ ::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
+ scoped_destructor<A> d(this->a_, vp);
+ *p = ::boost::move(*vp);
+ d.release();
this->used_ = true;
}
}
@@ -295,8 +302,17 @@
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!this->used_){
- *p = boost::move(value_type(
- ::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
+ alloc_traits::construct(this->a_, vp,
+ ::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
+ try {
+ *p = ::boost::move(*vp);
+ } catch (...) {
+ alloc_traits::destroy(this->a_, vp);
+ throw;
+ }
+ alloc_traits::destroy(this->a_, vp);
this->used_ = true;
}
}
@@ -337,13 +353,13 @@
\
virtual void uninitialized_copy_remaining_to(Iterator p) \
{ \
- if(!used_){ \
+ if(!this->used_){ \
alloc_traits::construct \
- ( a_ \
+ ( this->a_ \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
- used_ = true; \
+ this->used_ = true; \
} \
} \
\
@@ -352,13 +368,13 @@
{ \
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!used_){ \
+ if(!this->used_){ \
alloc_traits::construct \
- ( a_ \
+ ( this->a_ \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
- used_ = true; \
+ this->used_ = true; \
} \
} \
} \
@@ -382,6 +398,7 @@
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > base_t; \
typedef typename base_t::value_type value_type; \
typedef typename base_t::difference_type difference_type; \
+ typedef boost::container::allocator_traits<A> alloc_traits; \
\
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
@@ -391,10 +408,13 @@
virtual void copy_remaining_to(Iterator p) \
{ \
if(!this->used_){ \
- value_type v BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- *p = boost::move(v); \
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
+ alloc_traits::construct(this->a_, vp \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
+ scoped_destructor<A> d(this->a_, vp); \
+ *p = ::boost::move(*vp); \
+ d.release(); \
this->used_ = true; \
} \
} \
@@ -405,10 +425,13 @@
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!this->used_){ \
- value_type v BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- *p = boost::move(v); \
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
+ alloc_traits::construct(this->a_, vp \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
+ scoped_destructor<A> d(this->a_, vp); \
+ *p = ::boost::move(*vp); \
+ d.release(); \
this->used_ = true; \
} \
} \
Modified: branches/release/boost/container/detail/algorithms.hpp
==============================================================================
--- branches/release/boost/container/detail/algorithms.hpp (original)
+++ branches/release/boost/container/detail/algorithms.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (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
Modified: branches/release/boost/container/detail/allocation_type.hpp
==============================================================================
--- branches/release/boost/container/detail/allocation_type.hpp (original)
+++ branches/release/boost/container/detail/allocation_type.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/config_begin.hpp
==============================================================================
--- branches/release/boost/container/detail/config_begin.hpp (original)
+++ branches/release/boost/container/detail/config_begin.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -45,4 +45,5 @@
// with /GR-; unpredictable behavior may result
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
+ #pragma warning (disable : 4584) // X is already a base-class of Y
#endif //BOOST_MSVC
Modified: branches/release/boost/container/detail/config_end.hpp
==============================================================================
--- branches/release/boost/container/detail/config_end.hpp (original)
+++ branches/release/boost/container/detail/config_end.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/destroyers.hpp
==============================================================================
--- branches/release/boost/container/detail/destroyers.hpp (original)
+++ branches/release/boost/container/detail/destroyers.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (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
@@ -21,7 +21,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
namespace boost {
namespace container {
@@ -85,6 +85,9 @@
void increment_size(size_type inc)
{ m_n += inc; }
+
+ void increment_size_backwards(size_type inc)
+ { m_n += inc; m_p -= inc; }
~scoped_destructor_n()
{
@@ -115,10 +118,38 @@
void increment_size(size_type)
{}
+ void increment_size_backwards(size_type)
+ {}
+
void release()
{}
};
+template<class A>
+class scoped_destructor
+{
+ typedef boost::container::allocator_traits<A> AllocTraits;
+ public:
+ typedef typename A::value_type value_type;
+ scoped_destructor(A &a, value_type *pv)
+ : pv_(pv), a_(a)
+ {}
+
+ ~scoped_destructor()
+ {
+ if(pv_){
+ AllocTraits::destroy(a_, pv_);
+ }
+ }
+
+ void release()
+ { pv_ = 0; }
+
+ private:
+ value_type *pv_;
+ A &a_;
+};
+
template <class Allocator>
class allocator_destroyer
{
Modified: branches/release/boost/container/detail/flat_tree.hpp
==============================================================================
--- branches/release/boost/container/detail/flat_tree.hpp (original)
+++ branches/release/boost/container/detail/flat_tree.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -102,11 +102,19 @@
{}
Data(const Data &d)
- : value_compare(d), m_vect(d.m_vect)
+ : value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect)
{}
Data(BOOST_RV_REF(Data) d)
- : value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
+ : value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
+ {}
+
+ Data(const Data &d, const A &a)
+ : value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
+ {}
+
+ Data(BOOST_RV_REF(Data) d, const A &a)
+ : value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
{}
Data(const Compare &comp)
@@ -185,6 +193,14 @@
: m_data(boost::move(x.m_data))
{ }
+ flat_tree(const flat_tree& x, const allocator_type &a)
+ : m_data(x.m_data, a)
+ { }
+
+ flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
+ : m_data(boost::move(x.m_data), a)
+ { }
+
template <class InputIterator>
flat_tree( ordered_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare()
@@ -285,7 +301,6 @@
return ret;
}
-
iterator insert_equal(const value_type& val)
{
iterator i = this->upper_bound(KeyOfValue()(val));
@@ -323,14 +338,14 @@
iterator insert_equal(const_iterator pos, const value_type& val)
{
insert_commit_data data;
- priv_insert_equal_prepare(pos, val, data);
+ this->priv_insert_equal_prepare(pos, val, data);
return priv_insert_commit(data, val);
}
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
{
insert_commit_data data;
- priv_insert_equal_prepare(pos, mval, data);
+ this->priv_insert_equal_prepare(pos, mval, data);
return priv_insert_commit(data, boost::move(mval));
}
@@ -346,7 +361,15 @@
{
typedef typename
std::iterator_traits<InIt>::iterator_category ItCat;
- priv_insert_equal(first, last, ItCat());
+ this->priv_insert_equal(first, last, ItCat());
+ }
+
+ template <class InIt>
+ void insert_equal(ordered_range_t, InIt first, InIt last)
+ {
+ typedef typename
+ std::iterator_traits<InIt>::iterator_category ItCat;
+ this->priv_insert_equal(ordered_range_t(), first, last, ItCat());
}
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -390,7 +413,7 @@
{
value_type &&val = value_type(boost::forward<Args>(args)...);
insert_commit_data data;
- priv_insert_equal_prepare(hint, val, data);
+ this->priv_insert_equal_prepare(hint, val, data);
return priv_insert_commit(data, boost::move(val));
}
@@ -450,7 +473,7 @@
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \
insert_commit_data data; \
- priv_insert_equal_prepare(hint, val, data); \
+ this->priv_insert_equal_prepare(hint, val, data); \
return priv_insert_commit(data, boost::move(val)); \
} \
//!
@@ -730,10 +753,39 @@
return std::pair<RanIt, RanIt>(first, first);
}
- template <class FwdIt>
- void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ template <class BidirIt>
+ void priv_insert_equal(ordered_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
{
size_type len = static_cast<size_type>(std::distance(first, last));
+ const size_type BurstSize = 16;
+ size_type positions[BurstSize];
+
+ while(len){
+ const size_type burst = len < BurstSize ? len : BurstSize;
+ len -= burst;
+ const iterator beg(this->cbegin());
+ iterator pos;
+ for(size_type i = 0; i != burst; ++i){
+ pos = this->upper_bound(KeyOfValue()(*first));
+ positions[i] = static_cast<size_type>(pos - beg);
+ ++first;
+ }
+ this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
+ }
+ }
+
+ template <class FwdIt>
+ void priv_insert_equal_forward(ordered_range_t, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ { this->priv_insert_equal(first, last, std::forward_iterator_tag()); }
+
+ template <class InIt>
+ void priv_insert_equal(ordered_range_t, InIt first, InIt last, std::input_iterator_tag)
+ { this->priv_insert_equal(first, last, std::input_iterator_tag()); }
+
+ template <class FwdIt>
+ void priv_insert_equal_forward(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ const size_type len = static_cast<size_type>(std::distance(first, last));
this->reserve(this->size()+len);
this->priv_insert_equal(first, last, std::input_iterator_tag());
}
Modified: branches/release/boost/container/detail/function_detector.hpp
==============================================================================
--- branches/release/boost/container/detail/function_detector.hpp (original)
+++ branches/release/boost/container/detail/function_detector.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2009-2011.
+// (C) Copyright Ion Gaztanaga 2009-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
Modified: branches/release/boost/container/detail/iterators.hpp
==============================================================================
--- branches/release/boost/container/detail/iterators.hpp (original)
+++ branches/release/boost/container/detail/iterators.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
@@ -21,7 +21,7 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
@@ -513,7 +513,7 @@
container_detail::tuple<Args&...> args_;
};
-#else
+#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template <) \
@@ -522,16 +522,16 @@
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
{ \
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
- BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
+ ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
+ BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
\
template<class A, class T> \
void operator()(A &a, T *ptr) \
{ \
allocator_traits<A>::construct \
- (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
+ (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
} \
- BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
+ BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
Modified: branches/release/boost/container/detail/math_functions.hpp
==============================================================================
--- branches/release/boost/container/detail/math_functions.hpp (original)
+++ branches/release/boost/container/detail/math_functions.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Stephen Cleary 2000.
-// (C) Copyright Ion Gaztanaga 2007-2011.
+// (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
Modified: branches/release/boost/container/detail/mpl.hpp
==============================================================================
--- branches/release/boost/container/detail/mpl.hpp (original)
+++ branches/release/boost/container/detail/mpl.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (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
Modified: branches/release/boost/container/detail/multiallocation_chain.hpp
==============================================================================
--- branches/release/boost/container/detail/multiallocation_chain.hpp (original)
+++ branches/release/boost/container/detail/multiallocation_chain.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/node_alloc_holder.hpp
==============================================================================
--- branches/release/boost/container/detail/node_alloc_holder.hpp (original)
+++ branches/release/boost/container/detail/node_alloc_holder.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -27,7 +27,7 @@
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp>
@@ -36,6 +36,7 @@
#endif
#include <boost/container/detail/algorithms.hpp>
+#include <new>
namespace boost {
@@ -259,47 +260,21 @@
void deallocate_one(const NodePtr &p, allocator_v2)
{ this->node_alloc().deallocate_one(p); }
-/*
- template<class A, class Convertible1, class Convertible2>
- static void construct(A &a, const NodePtr &ptr,
- BOOST_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
- {
- typedef typename Node::hook_type hook_type;
- typedef typename Node::value_type::first_type first_type;
- typedef typename Node::value_type::second_type second_type;
- Node *nodeptr = container_detail::to_raw_pointer(ptr);
-
- //Hook constructor does not throw
- allocator_traits<A>::construct(a, static_cast<hook_type*>(nodeptr));
-
- //Now construct pair members_holder
- value_type *valueptr = &nodeptr->get_data();
- allocator_traits<A>::construct(a, &valueptr->first, boost::move(value.first));
- BOOST_TRY{
- allocator_traits<A>::construct(a, &valueptr->second, boost::move(value.second));
- }
- BOOST_CATCH(...){
- allocator_traits<A>::destroy(a, &valueptr->first);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-*/
+
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-/*
- template<class A, class ...Args>
- static void construct(A &a, const NodePtr &ptr, Args &&...args)
- {
- }
-*/
+
template<class ...Args>
NodePtr create_node(Args &&...args)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
- (this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward<Args>(args)...);
+ ( this->node_alloc()
+ , container_detail::addressof(p->m_data), boost::forward<Args>(args)...);
node_deallocator.release();
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
}
@@ -313,9 +288,11 @@
NodePtr p = this->allocate_one(); \
Deallocator node_deallocator(p, this->node_alloc()); \
allocator_traits<NodeAlloc>::construct \
- (this->node_alloc(), container_detail::to_raw_pointer(p) \
+ (this->node_alloc(), container_detail::addressof(p->m_data) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
node_deallocator.release(); \
+ typedef typename Node::hook_type hook_type; \
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type; \
return (p); \
} \
//!
@@ -329,8 +306,11 @@
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
- ::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
+ ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
node_deallocator.release();
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
}
@@ -364,8 +344,11 @@
mem.pop_front();
//This can throw
constructed = 0;
- boost::container::construct_in_place(this->node_alloc(), p, beg);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
++constructed;
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
//This can throw in some containers (predicate might throw)
inserter(*p);
}
Modified: branches/release/boost/container/detail/node_pool_impl.hpp
==============================================================================
--- branches/release/boost/container/detail/node_pool_impl.hpp (original)
+++ branches/release/boost/container/detail/node_pool_impl.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/pair.hpp
==============================================================================
--- branches/release/boost/container/detail/pair.hpp (original)
+++ branches/release/boost/container/detail/pair.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (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
@@ -22,6 +22,8 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
#include <utility> //std::pair
@@ -62,6 +64,33 @@
struct piecewise_construct_t { };
static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
+/*
+template <class T1, class T2>
+struct pair
+{
+ template <class U, class V> pair(pair<U, V>&& p);
+ template <class... Args1, class... Args2>
+ pair(piecewise_construct_t, tuple<Args1...> first_args,
+ tuple<Args2...> second_args);
+
+ template <class U, class V> pair& operator=(const pair<U, V>& p);
+ pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
+ is_nothrow_move_assignable<T2>::value);
+ template <class U, class V> pair& operator=(pair<U, V>&& p);
+
+ void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
+ noexcept(swap(second, p.second)));
+};
+
+template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
+*/
+
+
template <class T1, class T2>
struct pair
{
@@ -79,47 +108,40 @@
pair()
: first(), second()
{}
-/*
- //pair from two values
- pair(const T1 &t1, const T2 &t2)
- : first(t1)
- , second(t2)
- {}
-
-
- //pair from two values
- pair(BOOST_RV_REF(T1) t1, BOOST_RV_REF(T2) t2)
- : first(::boost::move(t1))
- , second(::boost::move(t2))
- {}
-*/
- template<class U, class V>
- pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
- : first(::boost::forward<U>(u))
- , second(::boost::forward<V>(v))
- {}
//pair copy assignment
pair(const pair& x)
: first(x.first), second(x.second)
{}
+ //pair move constructor
+ pair(BOOST_RV_REF(pair) p)
+ : first(::boost::move(p.first)), second(::boost::move(p.second))
+ {}
+
template <class D, class S>
pair(const pair<D, S> &p)
: first(p.first), second(p.second)
{}
- //pair move constructor
- pair(BOOST_RV_REF(pair) p)
+ template <class D, class S>
+ pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second))
{}
- template <class D, class S>
- pair(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
- : first(::boost::move(p.first)), second(::boost::move(p.second))
+ //pair from two values
+ pair(const T1 &t1, const T2 &t2)
+ : first(t1)
+ , second(t2)
+ {}
+
+ template<class U, class V>
+ pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
+ : first(::boost::forward<U>(u))
+ , second(::boost::forward<V>(v))
{}
- //std::pair copy constructor
+ //And now compatibility with std::pair
pair(const std::pair<T1, T2>& x)
: first(x.first), second(x.second)
{}
@@ -129,17 +151,20 @@
: first(p.first), second(p.second)
{}
- //std::pair move constructor
- template <class D, class S>
- pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second))
{}
- pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ template <class D, class S>
+ pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second))
{}
//piecewise_construct missing
+ //template <class U, class V> pair(pair<U, V>&& p);
+ //template <class... Args1, class... Args2>
+ // pair(piecewise_construct_t, tuple<Args1...> first_args,
+ // tuple<Args2...> second_args);
/*
//Variadic versions
template<class U>
@@ -179,14 +204,6 @@
return *this;
}
- template <class D, class S>
- pair& operator=(const pair<D, S>&p)
- {
- first = p.first;
- second = p.second;
- return *this;
- }
-
//pair move assignment
pair& operator=(BOOST_RV_REF(pair) p)
{
@@ -196,7 +213,23 @@
}
template <class D, class S>
- pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+ typename ::boost::container::container_detail::enable_if_c
+ < !(::boost::container::container_detail::is_same<T1, D>::value &&
+ ::boost::container::container_detail::is_same<T2, S>::value)
+ , pair &>::type
+ operator=(const pair<D, S>&p)
+ {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+
+ template <class D, class S>
+ typename ::boost::container::container_detail::enable_if_c
+ < !(::boost::container::container_detail::is_same<T1, D>::value &&
+ ::boost::container::container_detail::is_same<T2, S>::value)
+ , pair &>::type
+ operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
@@ -220,7 +253,7 @@
}
//std::pair move assignment
- pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
@@ -228,7 +261,7 @@
}
template <class D, class S>
- pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
Modified: branches/release/boost/container/detail/pool_common.hpp
==============================================================================
--- branches/release/boost/container/detail/pool_common.hpp (original)
+++ branches/release/boost/container/detail/pool_common.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/preprocessor.hpp
==============================================================================
--- branches/release/boost/container/detail/preprocessor.hpp (original)
+++ branches/release/boost/container/detail/preprocessor.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (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)
//
@@ -62,6 +62,10 @@
//!
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
+#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
+const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
+//!
+
#ifndef BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM(U, u) \
U && u \
@@ -74,17 +78,16 @@
#ifndef BOOST_NO_RVALUE_REFERENCES
- #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
- #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
- //!
+ #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
- #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ #else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
- #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
- //!
+ #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
+ //!
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
@@ -127,7 +130,7 @@
#else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
- boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
+ ::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
//!
#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
@@ -140,11 +143,11 @@
#define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
-boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
-boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
+::boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
//!
#define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
@@ -152,7 +155,11 @@
//!
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
- BOOST_PP_CAT(class P, n) = void \
+ BOOST_PP_CAT(class P, n) = void \
+//!
+
+#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
+ BOOST_PP_CAT(class P, n) = default_type \
//!
#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
Modified: branches/release/boost/container/detail/stored_ref.hpp
==============================================================================
--- branches/release/boost/container/detail/stored_ref.hpp (original)
+++ branches/release/boost/container/detail/stored_ref.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/transform_iterator.hpp
==============================================================================
--- branches/release/boost/container/detail/transform_iterator.hpp (original)
+++ branches/release/boost/container/detail/transform_iterator.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
Modified: branches/release/boost/container/detail/tree.hpp
==============================================================================
--- branches/release/boost/container/detail/tree.hpp (original)
+++ branches/release/boost/container/detail/tree.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -27,7 +27,7 @@
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -90,70 +90,38 @@
>::type type;
};
+//This trait is used to type-pun std::pair because in C++03
+//compilers std::pair is useless for C++11 features
template<class T>
-struct rbtree_type
+struct rbtree_internal_data_type
{
typedef T type;
};
template<class T1, class T2>
-struct rbtree_type< std::pair<T1, T2> >
+struct rbtree_internal_data_type< std::pair<T1, T2> >
{
typedef pair<T1, T2> type;
};
+
+//The node to be store in the tree
template <class T, class VoidPointer>
struct rbtree_node
: public rbtree_hook<VoidPointer>::type
{
private:
- BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
+ //BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
+ rbtree_node();
public:
typedef typename rbtree_hook<VoidPointer>::type hook_type;
typedef T value_type;
- typedef typename rbtree_type<T>::type internal_type;
+ typedef typename rbtree_internal_data_type<T>::type internal_type;
typedef rbtree_node<T, VoidPointer> node_type;
- rbtree_node()
- : m_data()
- {}
-
- rbtree_node(const rbtree_node &other)
- : m_data(other.m_data)
- {}
-
- rbtree_node(BOOST_RV_REF(rbtree_node) other)
- : m_data(boost::move(other.m_data))
- {}
-
- #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
- template<class ...Args>
- rbtree_node(Args &&...args)
- : m_data(boost::forward<Args>(args)...)
- {}
- #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
- rbtree_node &operator=(const rbtree_node &other)
- { do_assign(other.m_data); return *this; }
-
- rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
- { do_move(other.m_data); return *this; }
-
T &get_data()
{
T* ptr = reinterpret_cast<T*>(&this->m_data);
@@ -166,7 +134,6 @@
return *ptr;
}
- private:
internal_type m_data;
template<class A, class B>
@@ -188,22 +155,22 @@
{ m_data = v; }
template<class A, class B>
- void do_move(std::pair<const A, B> &p)
+ void do_move_assign(std::pair<const A, B> &p)
{
- const_cast<A&>(m_data.first) = boost::move(p.first);
- m_data.second = boost::move(p.second);
+ const_cast<A&>(m_data.first) = ::boost::move(p.first);
+ m_data.second = ::boost::move(p.second);
}
template<class A, class B>
- void do_move(pair<const A, B> &p)
+ void do_move_assign(pair<const A, B> &p)
{
- const_cast<A&>(m_data.first) = boost::move(p.first);
- m_data.second = boost::move(p.second);
+ const_cast<A&>(m_data.first) = ::boost::move(p.first);
+ m_data.second = ::boost::move(p.second);
}
template<class V>
- void do_move(V &v)
- { m_data = boost::move(v); }
+ void do_move_assign(V &v)
+ { m_data = ::boost::move(v); }
};
}//namespace container_detail {
@@ -282,7 +249,7 @@
//First recycle a node (this can't throw)
try{
//This can throw
- *p = other;
+ p->do_assign(other.m_data);
return p;
}
catch(...){
@@ -295,7 +262,7 @@
}
}
else{
- return m_holder.create_node(other);
+ return m_holder.create_node(other.m_data);
}
}
@@ -319,7 +286,7 @@
//First recycle a node (this can't throw)
try{
//This can throw
- *p = boost::move(other);
+ p->do_move_assign(const_cast<Node &>(other).m_data);
return p;
}
catch(...){
@@ -332,7 +299,7 @@
}
}
else{
- return m_holder.create_node(other);
+ return m_holder.create_node(other.m_data);
}
}
@@ -478,8 +445,10 @@
iterator(){}
//Pointer like operators
- reference operator*() const { return this->m_it->get_data(); }
- pointer operator->() const { return pointer(&this->m_it->get_data()); }
+ reference operator*() const
+ { return this->m_it->get_data(); }
+ pointer operator->() const
+ { return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data()); }
//Increment / Decrement
iterator& operator++()
@@ -532,9 +501,28 @@
}
rbtree(BOOST_RV_REF(rbtree) x)
- : AllocHolder(boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
+ : AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
{}
+ rbtree(const rbtree& x, const allocator_type &a)
+ : AllocHolder(a, x.key_comp())
+ {
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ }
+
+ rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
+ : AllocHolder(a, x.key_comp())
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->icont().swap(x.icont());
+ }
+ else{
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ }
+ }
+
~rbtree()
{} //AllocHolder clears the tree
@@ -552,7 +540,7 @@
//Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed
//automatically
- Icont other_tree(boost::move(this->icont()));
+ Icont other_tree(::boost::move(this->icont()));
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
@@ -578,7 +566,7 @@
if(this_alloc == x_alloc){
//Destroy and swap pointers
this->clear();
- this->icont() = boost::move(x.icont());
+ this->icont() = ::boost::move(x.icont());
//Move allocator if needed
this->AllocHolder::move_assign_alloc(x);
}
@@ -587,7 +575,7 @@
//Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed
//automatically
- Icont other_tree(boost::move(this->icont()));
+ Icont other_tree(::boost::move(this->icont()));
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
@@ -872,9 +860,9 @@
if(this->empty()){
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
- const_iterator end(this->end());
+ const_iterator hint(this->cend());
for( ; first != last; ++first)
- this->insert_unique(end, *first);
+ hint = this->insert_unique(hint, *first);
}
else{
for( ; first != last; ++first)
@@ -913,9 +901,9 @@
{
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
- const_iterator end(this->cend());
+ const_iterator hint(this->cend());
for( ; first != last; ++first)
- this->insert_equal(end, *first);
+ hint = this->insert_equal(hint, *first);
}
iterator erase(const_iterator position)
Modified: branches/release/boost/container/detail/type_traits.hpp
==============================================================================
--- branches/release/boost/container/detail/type_traits.hpp (original)
+++ branches/release/boost/container/detail/type_traits.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (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
@@ -29,6 +29,13 @@
struct nat{};
+template <typename U>
+struct LowPriorityConversion
+{
+ // Convertible from T with user-defined-conversion rank.
+ LowPriorityConversion(const U&) { }
+};
+
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;
Modified: branches/release/boost/container/detail/utilities.hpp
==============================================================================
--- branches/release/boost/container/detail/utilities.hpp (original)
+++ branches/release/boost/container/detail/utilities.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -21,13 +21,23 @@
#include <boost/move/move.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <algorithm>
namespace boost {
namespace container {
namespace container_detail {
+template <typename T>
+inline T* addressof(T& obj)
+{
+ return static_cast<T*>(
+ static_cast<void*>(
+ const_cast<char*>(
+ &reinterpret_cast<const char&>(obj)
+ )));
+}
+
template<class T>
const T &max_value(const T &a, const T &b)
{ return a > b ? a : b; }
@@ -262,6 +272,7 @@
return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
}
+
} //namespace container {
} //namespace boost {
Modified: branches/release/boost/container/detail/value_init.hpp
==============================================================================
--- branches/release/boost/container/detail/value_init.hpp (original)
+++ branches/release/boost/container/detail/value_init.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011.
+// (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
Modified: branches/release/boost/container/detail/variadic_templates_tools.hpp
==============================================================================
--- branches/release/boost/container/detail/variadic_templates_tools.hpp (original)
+++ branches/release/boost/container/detail/variadic_templates_tools.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/version_type.hpp
==============================================================================
--- branches/release/boost/container/detail/version_type.hpp (original)
+++ branches/release/boost/container/detail/version_type.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/boost/container/detail/workaround.hpp
==============================================================================
--- branches/release/boost/container/detail/workaround.hpp (original)
+++ branches/release/boost/container/detail/workaround.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -26,6 +26,11 @@
#define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
#endif
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
+ && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
+ #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
+#endif
+
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
Modified: branches/release/boost/container/flat_map.hpp
==============================================================================
--- branches/release/boost/container/flat_map.hpp (original)
+++ branches/release/boost/container/flat_map.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -26,7 +26,7 @@
#include <boost/container/detail/flat_tree.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/move/move.hpp>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -165,8 +165,13 @@
get_flat_tree_iterators
<pointer>::const_reverse_iterator const_reverse_iterator;
typedef A allocator_type;
+
+ //!Standard extension
typedef A stored_allocator_type;
+ //!Standard extension for C++03 compilers with non-movable std::pair
+ typedef impl_value_type movable_value_type;
+
public:
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
@@ -209,23 +214,38 @@
//! <b>Effects</b>: Copy constructs a flat_map.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_map(const flat_map<Key,T,Pred,A>& x)
+ flat_map(const flat_map& x)
: m_flat_tree(x.m_flat_tree) {}
//! <b>Effects</b>: Move constructs a flat_map.
//! Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_map(BOOST_RV_REF(flat_map) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{}
+ //! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_map(const flat_map& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
+ flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
+ : m_flat_tree(boost::move(x.m_flat_tree), a)
+ {}
+
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_map<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
+ flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: Move constructs a flat_map.
@@ -234,7 +254,7 @@
//! <b>Complexity</b>: Construct.
//!
//! <b>Postcondition</b>: x is emptied.
- flat_map<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_map) mx)
+ flat_map& operator=(BOOST_RV_REF(flat_map) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
@@ -484,7 +504,7 @@
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- std::pair<iterator,bool> insert(BOOST_RV_REF(impl_value_type) x)
+ std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
{
return container_detail::force<std::pair<iterator,bool> >
(m_flat_tree.insert_unique(boost::move(x)));
@@ -515,8 +535,11 @@
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
- { return container_detail::force_copy<iterator>
- (m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(container_detail::force<impl_value_type>(x)))); }
+ {
+ return container_detail::force_copy<iterator>
+ (m_flat_tree.insert_unique( container_detail::force<impl_const_iterator>(position)
+ , boost::move(container_detail::force<impl_value_type>(x))));
+ }
//! <b>Effects</b>: Inserts an element move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -527,7 +550,7 @@
//! right before p) plus insertion linear to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
- iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
+ iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
{
return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(x)));
@@ -704,13 +727,13 @@
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
- { return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+ { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
- { return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+ { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -916,6 +939,8 @@
typedef A allocator_type;
//Non-standard extension
typedef A stored_allocator_type;
+ //!Standard extension for C++03 compilers with non-movable std::pair
+ typedef impl_value_type movable_value_type;
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
@@ -960,28 +985,43 @@
//! <b>Effects</b>: Copy constructs a flat_multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_multimap(const flat_multimap<Key,T,Pred,A>& x)
+ flat_multimap(const flat_multimap& x)
: m_flat_tree(x.m_flat_tree) { }
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_multimap(BOOST_RV_REF(flat_multimap) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{ }
+ //! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multimap(const flat_multimap& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
+ : m_flat_tree(boost::move(x.m_flat_tree), a)
+ { }
+
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_multimap<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
+ flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: this->swap(x.get()).
//!
//! <b>Complexity</b>: Constant.
- flat_multimap<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_multimap) mx)
+ flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
@@ -1359,14 +1399,14 @@
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
- { return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+ { return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator>
equal_range(const key_type& x) const
- { return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+ { return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
Modified: branches/release/boost/container/flat_set.hpp
==============================================================================
--- branches/release/boost/container/flat_set.hpp (original)
+++ branches/release/boost/container/flat_set.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -100,14 +100,14 @@
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
- //! <b>Effects</b>: Defatuls constructs an empty flat_map.
+ //! <b>Effects</b>: Default constructs an empty flat_set.
//!
//! <b>Complexity</b>: Constant.
explicit flat_set()
: m_flat_tree()
{}
- //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! <b>Effects</b>: Constructs an empty flat_set using the specified
//! comparison object and allocator.
//!
//! <b>Complexity</b>: Constant.
@@ -116,7 +116,7 @@
: m_flat_tree(comp, a)
{}
- //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
@@ -143,31 +143,47 @@
: m_flat_tree(ordered_range, first, last, comp, a)
{}
- //! <b>Effects</b>: Copy constructs a map.
+ //! <b>Effects</b>: Copy constructs a set.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_set(const flat_set<T,Pred,A>& x)
- : m_flat_tree(x.m_flat_tree) {}
+ flat_set(const flat_set& x)
+ : m_flat_tree(x.m_flat_tree)
+ {}
- //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
+ //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_set(BOOST_RV_REF(flat_set) mx)
: m_flat_tree(boost::move(mx.m_flat_tree))
{}
+ //! <b>Effects</b>: Copy constructs a set using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set(const flat_set& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a set using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
+ flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a)
+ : m_flat_tree(boost::move(mx.m_flat_tree), a)
+ {}
+
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_set<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
+ flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
- //! <b>Effects</b>: Makes *this a copy of x.
+ //! <b>Effects</b>: Makes *this a copy of the previous value of xx.
//!
//! <b>Complexity</b>: Linear in x.size().
- flat_set<T,Pred,A>& operator=(BOOST_RV_REF(flat_set) mx)
+ flat_set& operator=(BOOST_RV_REF(flat_set) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
@@ -729,7 +745,7 @@
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
- //! <b>Effects</b>: Defatuls constructs an empty flat_map.
+ //! <b>Effects</b>: Default constructs an empty flat_multiset.
//!
//! <b>Complexity</b>: Constant.
explicit flat_multiset()
@@ -761,17 +777,47 @@
: m_flat_tree(ordered_range, first, last, comp, a)
{}
- flat_multiset(const flat_multiset<T,Pred,A>& x)
- : m_flat_tree(x.m_flat_tree) {}
+ //! <b>Effects</b>: Copy constructs a flat_multiset.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset(const flat_multiset& x)
+ : m_flat_tree(x.m_flat_tree)
+ {}
- flat_multiset(BOOST_RV_REF(flat_multiset) x)
- : m_flat_tree(boost::move(x.m_flat_tree))
+ //! <b>Effects</b>: Move constructs a flat_multiset. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_multiset(BOOST_RV_REF(flat_multiset) mx)
+ : m_flat_tree(boost::move(mx.m_flat_tree))
+ {}
+
+ //! <b>Effects</b>: Copy constructs a flat_multiset using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset(const flat_multiset& x, const allocator_type &a)
+ : m_flat_tree(x.m_flat_tree, a)
{}
- flat_multiset<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
+ //! <b>Effects</b>: Move constructs a flat_multiset using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
+ flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a)
+ : m_flat_tree(boost::move(mx.m_flat_tree), a)
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
- flat_multiset<T,Pred,A>& operator=(BOOST_RV_REF(flat_multiset) mx)
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
Modified: branches/release/boost/container/list.hpp
==============================================================================
--- branches/release/boost/container/list.hpp (original)
+++ branches/release/boost/container/list.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -65,30 +65,7 @@
struct list_node
: public list_hook<VoidPointer>::type
{
-
- list_node()
- : m_data()
- {}
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- template<class ...Args>
- list_node(Args &&...args)
- : m_data(boost::forward<Args>(args)...)
- {}
-
- #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- list_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-
+ typedef typename list_hook<VoidPointer>::type hook_type;
T m_data;
};
@@ -374,6 +351,34 @@
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
{}
+ //! <b>Effects</b>: Copy constructs a list using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ list(const list& x, const allocator_type &a)
+ : AllocHolder(a)
+ { this->insert(this->cbegin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor sing the specified allocator.
+ //! Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ list(BOOST_RV_REF(list) x, const allocator_type &a)
+ : AllocHolder(a)
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->icont().swap(x.icont());
+ }
+ else{
+ this->insert(this->cbegin(), x.begin(), x.end());
+ }
+ }
+
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the list.
//!
Modified: branches/release/boost/container/map.hpp
==============================================================================
--- branches/release/boost/container/map.hpp (original)
+++ branches/release/boost/container/map.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -158,7 +158,7 @@
: m_tree(first, last, comp, a, true)
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
@@ -175,29 +175,52 @@
: m_tree(ordered_range, first, last, comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a map.
//!
//! <b>Complexity</b>: Linear in x.size().
- map(const map<Key,T,Pred,A>& x)
+ map(const map& x)
: m_tree(x.m_tree)
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
map(BOOST_RV_REF(map) x)
: m_tree(boost::move(x.m_tree))
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Copy constructs a map using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ map(const map& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Move constructs a map using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ map(BOOST_RV_REF(map) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -833,7 +856,7 @@
: m_tree(comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
@@ -848,7 +871,7 @@
: m_tree(first, last, comp, a, false)
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
@@ -864,27 +887,48 @@
: m_tree(ordered_range, first, last, comp, a)
{}
-
//! <b>Effects</b>: Copy constructs a multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
- multimap(const multimap<Key,T,Pred,A>& x)
+ multimap(const multimap& x)
: m_tree(x.m_tree)
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
multimap(BOOST_RV_REF(multimap) x)
: m_tree(boost::move(x.m_tree))
{
//Allocator type must be std::pair<CONST Key, T>
- BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Copy constructs a multimap.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multimap(const multimap& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Move constructs a multimap using the specified allocator.
+ //! Constructs *this using x's resources.
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
Modified: branches/release/boost/container/set.hpp
==============================================================================
--- branches/release/boost/container/set.hpp (original)
+++ branches/release/boost/container/set.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -144,16 +144,31 @@
//! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
set(BOOST_RV_REF(set) x)
: m_tree(boost::move(x.m_tree))
{}
- //! <b>Effects</b>: Makes *this a copy of x.
+ //! <b>Effects</b>: Copy constructs a set using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
+ set(const set& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a set using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ set(BOOST_RV_REF(set) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
{ m_tree = x.m_tree; return *this; }
@@ -716,13 +731,30 @@
//! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Construct.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
multiset(BOOST_RV_REF(multiset) x)
: m_tree(boost::move(x.m_tree))
{}
+ //! <b>Effects</b>: Copy constructs a multiset using the specified allocator.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multiset(const multiset& x, const allocator_type &a)
+ : m_tree(x.m_tree, a)
+ {}
+
+ //! <b>Effects</b>: Move constructs a multiset using the specified allocator.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
+ : m_tree(boost::move(x.m_tree), a)
+ {}
+
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
Modified: branches/release/boost/container/slist.hpp
==============================================================================
--- branches/release/boost/container/slist.hpp (original)
+++ branches/release/boost/container/slist.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
@@ -65,31 +65,7 @@
struct slist_node
: public slist_hook<VoidPointer>::type
{
-
- slist_node()
- : m_data()
- {}
-
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- template<class ...Args>
- slist_node(Args &&...args)
- : m_data(boost::forward<Args>(args)...)
- {}
-
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
+ typedef typename slist_hook<VoidPointer>::type hook_type;
T m_data;
};
@@ -391,6 +367,34 @@
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
{}
+ //! <b>Effects</b>: Copy constructs a list using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ slist(const slist& x, const allocator_type &a)
+ : AllocHolder(a)
+ { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves x's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocation or value_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ slist(BOOST_RV_REF(slist) x, const allocator_type &a)
+ : AllocHolder(a)
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->icont().swap(x.icont());
+ }
+ else{
+ this->insert(this->cbegin(), x.begin(), x.end());
+ }
+ }
+
//! <b>Effects</b>: Makes *this contain the same elements as x.
//!
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
Modified: branches/release/boost/container/stable_vector.hpp
==============================================================================
--- branches/release/boost/container/stable_vector.hpp (original)
+++ branches/release/boost/container/stable_vector.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// (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)
//
@@ -34,7 +34,7 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <algorithm>
@@ -78,10 +78,6 @@
{ return ptr;}
};
-template<class Ptr>
-inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
-{ return smart_ptr_type<Ptr>::get(ptr); }
-
template <class C>
class clear_on_destroy
{
@@ -110,13 +106,10 @@
template<class VoidPtr>
struct node_type_base
-{/*
- node_type_base(VoidPtr p)
- : up(p)
- {}*/
+{
node_type_base()
{}
- void set_pointer(VoidPtr p)
+ void set_pointer(const VoidPtr &p)
{ up = p; }
VoidPtr up;
@@ -126,33 +119,6 @@
struct node_type
: public node_type_base<VoidPointer>
{
- node_type()
- : value()
- {}
-
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- template<class ...Args>
- node_type(Args &&...args)
- : value(boost::forward<Args>(args)...)
- {}
-
- #else //BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif//BOOST_CONTAINER_PERFECT_FORWARDING
-
- void set_pointer(VoidPointer p)
- { node_type_base<VoidPointer>::set_pointer(p); }
-
T value;
};
@@ -206,17 +172,17 @@
private:
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
- return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
}
static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
{
- return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return const_node_type_ptr_t(static_cast<const node_type_t*>(container_detail::to_raw_pointer(p)));
}
static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
{
- return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
+ return void_ptr_ptr(static_cast<void_ptr*>(container_detail::to_raw_pointer(p)));
}
reference dereference() const
@@ -353,35 +319,37 @@
/// @endcond
-//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
-//!drop-in replacement implemented as a node container, offering iterator and reference
-//!stability.
+//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
+//! drop-in replacement implemented as a node container, offering iterator and reference
+//! stability.
//!
-//!More details taken the author's blog: ( Introducing stable_vector)
+//! More details taken the author's blog:
+//! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
+//! Introducing stable_vector</a>)
//!
-//!We present stable_vector, a fully STL-compliant stable container that provides
-//!most of the features of std::vector except element contiguity.
+//! We present stable_vector, a fully STL-compliant stable container that provides
+//! most of the features of std::vector except element contiguity.
//!
-//!General properties: stable_vector satisfies all the requirements of a container,
-//!a reversible container and a sequence and provides all the optional operations
-//!present in std::vector. Like std::vector, iterators are random access.
-//!stable_vector does not provide element contiguity; in exchange for this absence,
-//!the container is stable, i.e. references and iterators to an element of a stable_vector
-//!remain valid as long as the element is not erased, and an iterator that has been
-//!assigned the return value of end() always remain valid until the destruction of
-//!the associated stable_vector.
+//! General properties: stable_vector satisfies all the requirements of a container,
+//! a reversible container and a sequence and provides all the optional operations
+//! present in std::vector. Like std::vector, iterators are random access.
+//! stable_vector does not provide element contiguity; in exchange for this absence,
+//! the container is stable, i.e. references and iterators to an element of a stable_vector
+//! remain valid as long as the element is not erased, and an iterator that has been
+//! assigned the return value of end() always remain valid until the destruction of
+//! the associated stable_vector.
//!
-//!Operation complexity: The big-O complexities of stable_vector operations match
-//!exactly those of std::vector. In general, insertion/deletion is constant time at
-//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
-//!does not internally perform any value_type destruction, copy or assignment
-//!operations other than those exactly corresponding to the insertion of new
-//!elements or deletion of stored elements, which can sometimes compensate in terms
-//!of performance for the extra burden of doing more pointer manipulation and an
-//!additional allocation per element.
+//! Operation complexity: The big-O complexities of stable_vector operations match
+//! exactly those of std::vector. In general, insertion/deletion is constant time at
+//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
+//! does not internally perform any value_type destruction, copy or assignment
+//! operations other than those exactly corresponding to the insertion of new
+//! elements or deletion of stored elements, which can sometimes compensate in terms
+//! of performance for the extra burden of doing more pointer manipulation and an
+//! additional allocation per element.
//!
-//!Exception safety: As stable_vector does not internally copy elements around, some
-//!operations provide stronger exception safety guarantees than in std::vector:
+//! Exception safety: As stable_vector does not internally copy elements around, some
+//! operations provide stronger exception safety guarantees than in std::vector:
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> >
#else
@@ -524,7 +492,7 @@
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- explicit stable_vector(const A& al)
+ explicit stable_vector(const allocator_type& al)
: internal_data(al),impl(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
@@ -538,7 +506,7 @@
//!
//! <b>Complexity</b>: Linear to n.
explicit stable_vector(size_type n)
- : internal_data(A()),impl(A())
+ : internal_data(),impl()
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n);
@@ -553,7 +521,7 @@
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
- stable_vector(size_type n, const T& t, const A& al=A())
+ stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
: internal_data(al),impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -570,7 +538,7 @@
//!
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InputIterator>
- stable_vector(InputIterator first,InputIterator last,const A& al=A())
+ stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
: internal_data(al),impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -607,6 +575,40 @@
this->priv_swap_members(x);
}
+ //! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ stable_vector(const stable_vector& x, const allocator_type &a)
+ : internal_data(a), impl(a)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), x.begin(), x.end());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
+ stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
+ : internal_data(a), impl(a)
+ {
+ if(this->node_alloc() == x.node_alloc()){
+ this->priv_swap_members(x);
+ }
+ else{
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), x.begin(), x.end());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+ }
+
//! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
//! and used memory is deallocated.
//!
@@ -709,7 +711,7 @@
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator()const {return node_alloc();}
+ allocator_type get_allocator()const {return this->node_alloc();}
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -1137,7 +1139,7 @@
void emplace_back(Args &&...args)
{
typedef emplace_functor<Args...> EmplaceFunctor;
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
}
@@ -1157,7 +1159,7 @@
//Just call more general insert(pos, size, value) and return iterator
size_type pos_n = position - cbegin();
typedef emplace_functor<Args...> EmplaceFunctor;
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
return iterator(this->begin() + pos_n);
@@ -1172,7 +1174,7 @@
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
@@ -1186,7 +1188,7 @@
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \
- typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
@@ -1482,12 +1484,12 @@
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
- return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
}
static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
{
- return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
+ return node_type_base_ptr_t(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p)));
}
static value_type& value(const void_ptr &p)
@@ -1529,7 +1531,9 @@
{
node_type_ptr_t p = this->allocate_one();
try{
- boost::container::construct_in_place(this->node_alloc(), &*p, it);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), it);
+ //This does not throw
+ ::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(up);
}
catch(...){
@@ -1621,7 +1625,9 @@
p = mem.front();
mem.pop_front();
//This can throw
- boost::container::construct_in_place(this->node_alloc(), &*p, first);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+ //This does not throw
+ ::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(void_ptr_ptr(&it[i]));
++first;
it[i] = p;
@@ -1650,7 +1656,9 @@
break;
}
//This can throw
- boost::container::construct_in_place(this->node_alloc(), &*p, first);
+ boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+ //This does not throw
+ ::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(void_ptr_ptr(&it[i]));
++first;
it[i]=p;
Modified: branches/release/boost/container/string.hpp
==============================================================================
--- branches/release/boost/container/string.hpp (original)
+++ branches/release/boost/container/string.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -43,7 +43,7 @@
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_type.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp>
#include <boost/static_assert.hpp>
@@ -620,12 +620,12 @@
//!
//! <b>Postcondition</b>: x == *this.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //! <b>Throws</b>: If allocator_type's default constructor throws.
basic_string(const basic_string& s)
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
{ this->priv_range_initialize(s.begin(), s.end()); }
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //! <b>Effects</b>: Move constructor. Moves s's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
@@ -634,6 +634,32 @@
: base_t(boost::move((base_t&)s))
{}
+ //! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocation throws.
+ basic_string(const basic_string& s, const allocator_type &a)
+ : base_t(a)
+ { this->priv_range_initialize(s.begin(), s.end()); }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves s's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocation throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == s.get_allocator(), linear otherwise.
+ basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
+ : base_t(a)
+ {
+ if(a == this->alloc()){
+ this->swap_data(s);
+ }
+ else{
+ this->priv_range_initialize(s.begin(), s.end());
+ }
+ }
+
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by a specific number of characters of the s string.
basic_string(const basic_string& s, size_type pos, size_type n = npos,
Modified: branches/release/boost/container/vector.hpp
==============================================================================
--- branches/release/boost/container/vector.hpp (original)
+++ branches/release/boost/container/vector.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -38,7 +38,7 @@
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/destroyers.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/move/move.hpp>
#include <boost/move/move_helpers.hpp>
@@ -46,6 +46,7 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/assert.hpp>
namespace boost {
namespace container {
@@ -540,6 +541,40 @@
: base_t(boost::move(mx.alloc()))
{ this->swap_members(mx); }
+ //! <b>Effects</b>: Copy constructs a vector using the specified allocator.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocation
+ //! throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ vector(const vector &x, const allocator_type &a)
+ : base_t(a)
+ {
+ this->assign( container_detail::to_raw_pointer(x.members_.m_start)
+ , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
+ }
+
+ //! <b>Effects</b>: Move constructor using the specified allocator.
+ //! Moves mx's resources to *this if a == allocator_type().
+ //! Otherwise copies values from x to *this.
+ //!
+ //! <b>Throws</b>: If allocation or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
+ vector(BOOST_RV_REF(vector) mx, const allocator_type &a)
+ : base_t(a)
+ {
+ if(mx.alloc() == a){
+ this->swap_members(mx);
+ }
+ else{
+ this->assign( container_detail::to_raw_pointer(mx.members_.m_start)
+ , container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size));
+ }
+ }
+
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the vector.
//!
@@ -1428,6 +1463,146 @@
}
}
+ public:
+ //Absolutely experimental. This function might change, disappear or simply crash!
+ template<class BiDirPosIt, class BiDirValueIt>
+ void insert_ordered_at(size_type element_count, BiDirPosIt last_position_it, BiDirValueIt last_value_it)
+ {
+ const size_type old_size_pos = this->size();
+ this->reserve(old_size_pos + element_count);
+ T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
+ size_type insertions_left = element_count;
+ size_type next_pos = old_size_pos;
+ size_type hole_size = element_count;
+
+ //Exception rollback. If any copy throws before the hole is filled, values
+ //already inserted/copied at the end of the buffer will be destroyed.
+ typename value_traits::ArrayDestructor past_hole_values_destroyer
+ (begin_ptr + old_size_pos + element_count, this->alloc(), size_type(0u));
+ //Loop for each insertion backwards, first moving the elements after the insertion point,
+ //then inserting the element.
+ while(insertions_left){
+ const size_type pos = static_cast<size_type>(*(--last_position_it));
+ BOOST_ASSERT(pos <= old_size_pos);
+ //Shift the range after the insertion point, function will take care if the shift
+ //crosses the size() boundary, using copy/move or uninitialized copy/move if necessary.
+ size_type new_hole_size = insert_ordered_at_shift_range(pos, next_pos, this->size(), insertions_left);
+ if(new_hole_size > 0){
+ //The hole was reduced by insert_ordered_at_shift_range so expand exception rollback range backwards
+ past_hole_values_destroyer.increment_size_backwards(next_pos - pos);
+ //Insert the new value in the hole
+ allocator_traits_type::construct(this->alloc(), begin_ptr + pos + insertions_left - 1, *(--last_value_it));
+ --new_hole_size;
+ if(new_hole_size == 0){
+ //Hole was just filled, disable exception rollback and change vector size
+ past_hole_values_destroyer.release();
+ this->members_.m_size += element_count;
+ }
+ else{
+ //The hole was reduced by the new insertion by one
+ past_hole_values_destroyer.increment_size_backwards(size_type(1u));
+ }
+ }
+ else{
+ if(hole_size){
+ //Hole was just filled by insert_ordered_at_shift_range, disable exception rollback and change vector size
+ past_hole_values_destroyer.release();
+ this->members_.m_size += element_count;
+ }
+ //Insert the new value in the already constructed range
+ begin_ptr[pos + insertions_left - 1] = *(--last_value_it);
+ }
+ --insertions_left;
+ hole_size = new_hole_size;
+ next_pos = pos;
+ }
+ }
+
+ //Takes the range pointed by [first_pos, last_pos) and shifts it to the right
+ //by 'shift_count'. 'limit_pos' marks the end of constructed elements.
+ //
+ //Precondition: first_pos <= last_pos <= limit_pos
+ //
+ //The shift operation might cross limit_pos so elements to moved beyond limit_pos
+ //are uninitialized_moved with an allocator. Other elements are moved.
+ //
+ //The shift operation might left uninitialized elements after limit_pos
+ //and the number of uninitialized elements is returned by the function.
+ //
+ //Old situation:
+ // first_pos last_pos old_limit
+ // | | |
+ // ____________V_______V__________________V_____________
+ //| prefix | range | suffix |raw_mem ~
+ //|____________|_______|__________________|_____________~
+ //
+ //New situation in Case A (hole_size == 0):
+ // range is moved through move assignments
+ //
+ // first_pos last_pos old_limit
+ // | | |
+ // ____________V_______V__________________V_____________
+ //| prefix' | | | range |suffix'|raw_mem ~
+ //|________________+______|___^___|_______|_____________~
+ // | |
+ // |_>_>_>_>_>^
+ //
+ //
+ //New situation in Case B (hole_size >= 0):
+ // range is moved through uninitialized moves
+ //
+ // first_pos last_pos old_limit
+ // | | |
+ // ____________V_______V__________________V________________
+ //| prefix' | | | [hole] | range |
+ //|_______________________________________|________|___^___|
+ // | |
+ // |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^
+ //
+ //New situation in Case C (hole_size == 0):
+ // range is moved through move assignments and uninitialized moves
+ //
+ // first_pos last_pos old_limit
+ // | | |
+ // ____________V_______V__________________V___
+ //| prefix' | | | range |
+ //|___________________________________|___^___|
+ // | |
+ // |_>_>_>_>_>_>_>_>_>_>_>^
+ size_type insert_ordered_at_shift_range(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
+ {
+ BOOST_ASSERT(first_pos <= last_pos);
+ BOOST_ASSERT(last_pos <= limit_pos);
+ //
+ T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
+
+ size_type hole_size = 0;
+ //Case A:
+ if((last_pos + shift_count) <= limit_pos){
+ //All move assigned
+ boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count);
+ }
+ //Case B:
+ else if((first_pos + shift_count) >= limit_pos){
+ //All uninitialized_moved
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count);
+ hole_size = last_pos + shift_count - limit_pos;
+ }
+ //Case C:
+ else{
+ //Some uninitialized_moved
+ T* const limit_ptr = begin_ptr + limit_pos;
+ T* const boundary_ptr = limit_ptr - shift_count;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), boundary_ptr, begin_ptr + last_pos, limit_ptr);
+ //The rest is move assigned
+ boost::move_backward(begin_ptr + first_pos, boundary_ptr, limit_ptr + shift_count);
+ }
+ return hole_size;
+ }
+
+ private:
void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
{
//n can't be 0, because there is nothing to do in that case
Modified: branches/release/boost/interprocess/detail/atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/atomic.hpp (original)
+++ branches/release/boost/interprocess/detail/atomic.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -117,23 +117,6 @@
: "cc");
return prev;
-/*
- asm volatile( "lock\n\t"
- "cmpxchg %3,%1"
- : "=a" (prev), "=m" (*(mem))
- : "0" (prev), "r" (with)
- : "memory", "cc");
-*/
-/*
- boost::uint32_t prev;
-
- asm volatile ("lock; cmpxchgl %1, %2"
- : "=a" (prev)
- : "r" (with), "m" (*(mem)), "0"(cmp));
- asm volatile("" : : : "memory");
-
- return prev;
-*/
}
//! Atomically add 'val' to an boost::uint32_t
@@ -158,14 +141,6 @@
);
return r;
-/*
- asm volatile( "lock\n\t; xaddl %0,%1"
- : "=r"(val), "=m"(*mem)
- : "0"(val), "m"(*mem));
- asm volatile("" : : : "memory");
-
- return val;
-*/
}
//! Atomically increment an apr_uint32_t by 1
@@ -208,17 +183,14 @@
{
boost::uint32_t prev, temp;
- asm volatile ("0:\n\t" // retry local label
- "lwarx %0,0,%2\n\t" // load prev and reserve
- "add %1,%0,%3\n\t" // temp = prev + val
- "stwcx. %1,0,%2\n\t" // conditionally store
- "bne- 0b" // start over if we lost
- // the reservation
- //XXX find a cleaner way to define the temp
- //it's not an output
- : "=&r" (prev), "=&r" (temp) // output, temp
- : "b" (mem), "r" (val) // inputs
- : "memory", "cc"); // clobbered
+ asm volatile ("1:\n\t"
+ "lwarx %0,0,%2\n\t"
+ "add %1,%0,%3\n\t"
+ "stwcx. %1,0,%2\n\t"
+ "bne- 1b"
+ : "=&r" (prev), "=&r" (temp)
+ : "b" (mem), "r" (val)
+ : "cc", "memory");
return prev;
}
@@ -233,19 +205,16 @@
{
boost::uint32_t prev;
- asm volatile ("0:\n\t" // retry local label
- "lwarx %0,0,%1\n\t" // load prev and reserve
- "cmpw %0,%3\n\t" // does it match cmp?
- "bne- 1f\n\t" // ...no, bail out
- "stwcx. %2,0,%1\n\t" // ...yes, conditionally
- // store with
- "bne- 0b\n\t" // start over if we lost
- // the reservation
- "1:" // exit local label
-
- : "=&r"(prev) // output
- : "b" (mem), "r" (with), "r"(cmp) // inputs
- : "memory", "cc"); // clobbered
+ asm volatile ("1:\n\t"
+ "lwarx %0,0,%1\n\t"
+ "cmpw %0,%3\n\t"
+ "bne- 2f\n\t"
+ "stwcx. %2,0,%1\n\t"
+ "bne- 1b\n\t"
+ "2:"
+ : "=&r"(prev)
+ : "b" (mem), "r"(cmp), "r" (with)
+ : "cc", "memory");
return prev;
}
@@ -275,56 +244,6 @@
} //namespace interprocess{
} //namespace boost{
-#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
-
-namespace boost {
-namespace interprocess {
-namespace ipcdetail{
-
-//! Atomically add 'val' to an boost::uint32_t
-//! "mem": pointer to the object
-//! "val": amount to add
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_add32
- (volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val); }
-
-//! Atomically increment an apr_uint32_t by 1
-//! "mem": pointer to the object
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
-{ return atomic_add32(mem, 1); }
-
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
-{ return atomic_add32(mem, (boost::uint32_t)-1); }
-
-//! Atomically read an boost::uint32_t from memory
-inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{ return *mem; }
-
-//! Compare an boost::uint32_t's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the value
-//! "with" what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_cas32
- (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with); }
-
-//! Atomically set an boost::uint32_t in memory
-//! "mem": pointer to the object
-//! "param": val value that the object will assume
-inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ *mem = val; }
-
-} //namespace ipcdetail{
-} //namespace interprocess{
-} //namespace boost{
-
#elif (defined(sun) || defined(__sun))
#include <atomic.h>
@@ -561,7 +480,57 @@
} //namespace ipcdetail
} //namespace interprocess
-} //namespace boost
+} //namespace boost
+
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail{
+
+//! Atomically add 'val' to an boost::uint32_t
+//! "mem": pointer to the object
+//! "val": amount to add
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_add32
+ (volatile boost::uint32_t *mem, boost::uint32_t val)
+{ return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val); }
+
+//! Atomically increment an apr_uint32_t by 1
+//! "mem": pointer to the object
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, 1); }
+
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, (boost::uint32_t)-1); }
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{ return *mem; }
+
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
+//! "mem": pointer to the value
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
+//! Returns the old value of *mem
+inline boost::uint32_t atomic_cas32
+ (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
+{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with); }
+
+//! Atomically set an boost::uint32_t in memory
+//! "mem": pointer to the object
+//! "param": val value that the object will assume
+inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
+{ *mem = val; }
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
#else
Modified: branches/release/boost/interprocess/detail/config_begin.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/config_begin.hpp (original)
+++ branches/release/boost/interprocess/detail/config_begin.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -44,4 +44,5 @@
// with /GR-; unpredictable behavior may result
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
+ #pragma warning (disable : 4250) // inherits 'x' via dominance
#endif
Modified: branches/release/boost/interprocess/detail/intermodule_singleton.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/intermodule_singleton.hpp (original)
+++ branches/release/boost/interprocess/detail/intermodule_singleton.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -18,1150 +18,15 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#include <boost/interprocess/windows_shared_memory.hpp>
-#endif
-
-#include <boost/interprocess/shared_memory_object.hpp>
-
-#include <boost/interprocess/offset_ptr.hpp>
-#include <boost/interprocess/sync/spin/mutex.hpp>
-#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
-#include <boost/interprocess/detail/managed_memory_impl.hpp>
-#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
-#include <boost/interprocess/indexes/iset_index.hpp>
-#include <boost/interprocess/creation_tags.hpp>
-#include <boost/interprocess/permissions.hpp>
-
-
-#include <boost/interprocess/detail/atomic.hpp>
-#include <boost/interprocess/detail/os_thread_functions.hpp>
-#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
-#include <boost/interprocess/detail/os_file_functions.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/type_traits/type_with_alignment.hpp>
-#include <boost/assert.hpp>
-#include <cstddef>
-#include <cstdio>
-#include <cstring>
-#include <string>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#include <fcntl.h>
-#include <io.h>
-
-#include <sys/locking.h>
-#else
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#ifdef BOOST_INTERPROCESS_WINDOWS
+ #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#endif
+#include <boost/interprocess/detail/portable_intermodule_singleton.hpp>
namespace boost{
namespace interprocess{
namespace ipcdetail{
-struct intermodule_singleton_mutex_family
-{
- typedef boost::interprocess::ipcdetail::spin_mutex mutex_type;
- typedef boost::interprocess::ipcdetail::spin_recursive_mutex recursive_mutex_type;
-};
-
-struct intermodule_types
-{
- //We must use offset_ptr since a loaded DLL can map the singleton holder shared memory
- //at a different address than other DLLs/main executables
- typedef rbtree_best_fit<intermodule_singleton_mutex_family, offset_ptr<void> > mem_algo;
- template<class Device, bool FileBased>
- struct open_or_create
- {
- typedef managed_open_or_create_impl
- <Device, mem_algo::Alignment, FileBased> type;
- };
-};
-
-template<class Device, bool FileBased>
-class basic_managed_global_memory
- : public basic_managed_memory_impl
- < char
- , intermodule_types::mem_algo
- , iset_index
- , intermodule_types::open_or_create<Device, FileBased>::type::ManagedOpenOrCreateUserOffset
- >
- , private intermodule_types::open_or_create<Device, FileBased>::type
-{
- /// @cond
- typedef typename intermodule_types::template open_or_create<Device, FileBased>::type base2_t;
-
- typedef basic_managed_memory_impl
- < char
- , intermodule_types::mem_algo
- , iset_index
- , base2_t::ManagedOpenOrCreateUserOffset
- > base_t;
-
- typedef create_open_func<base_t> create_open_func_t;
-
- basic_managed_global_memory *get_this_pointer()
- { return this; }
-
- public:
- typedef typename base_t::size_type size_type;
-
- private:
- typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
- BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_global_memory)
- /// @endcond
-
- public: //functions
-/*
- basic_managed_global_memory()
- {}
-
- basic_managed_global_memory(create_only_t create_only, const char *name,
- size_type size, const void *addr = 0, const permissions& perm = permissions())
- : base_t()
- , base2_t(create_only, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(), DoCreate), perm)
- {}
-*/
- basic_managed_global_memory (open_or_create_t open_or_create,
- const char *name, size_type size,
- const void *addr = 0, const permissions& perm = permissions())
- : base_t()
- , base2_t(open_or_create, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(),
- DoOpenOrCreate), perm)
- {}
-
- basic_managed_global_memory (open_only_t open_only, const char* name,
- const void *addr = 0)
- : base_t()
- , base2_t(open_only, name, read_write, addr,
- create_open_func_t(get_this_pointer(),
- DoOpen))
- {}
-
-/*
- basic_managed_global_memory (open_copy_on_write_t, const char* name,
- const void *addr = 0)
- : base_t()
- , base2_t(open_only, name, copy_on_write, addr,
- create_open_func_t(get_this_pointer(),
- DoOpen))
- {}
-
- //!Connects to a created shared memory and its segment manager.
- //!in read-only mode.
- //!This can throw.
- basic_managed_global_memory (open_read_only_t, const char* name,
- const void *addr = 0)
- : base_t()
- , base2_t(open_only, name, read_only, addr,
- create_open_func_t(get_this_pointer(),
- DoOpen))
- {}
-
- //!Moves the ownership of "moved"'s managed memory to *this.
- //!Does not throw
- basic_managed_global_memory(BOOST_RV_REF(basic_managed_global_memory) moved)
- {
- basic_managed_global_memory tmp;
- this->swap(moved);
- tmp.swap(moved);
- }
-
- //!Moves the ownership of "moved"'s managed memory to *this.
- //!Does not throw
- basic_managed_global_memory &operator=(BOOST_RV_REF(basic_managed_global_memory) moved)
- {
- basic_managed_global_memory tmp(boost::move(moved));
- this->swap(tmp);
- return *this;
- }*/
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-typedef basic_managed_global_memory<windows_shared_memory, false> windows_managed_global_memory;
-#endif
-
-typedef basic_managed_global_memory<shared_memory_object, true> managed_global_memory;
-
-namespace file_locking_helpers {
-
-inline void get_pid_creation_time_str(std::string &s)
-{
- std::stringstream stream;
- stream << get_current_process_id() << '_';
- stream.precision(6);
- stream << std::fixed << get_current_process_creation_time();
- s = stream.str();
-}
-
-inline void create_tmp_subdir_and_get_pid_based_filepath(const char *subdir_name, const char *file_prefix, OS_process_id_t pid, std::string &s, bool creation_time = false)
-{
- //Let's create a lock file for each process gmem that will mark if
- //the process is alive or not
- create_tmp_and_clean_old(s);
- s += "/";
- s += subdir_name;
- if(!open_or_create_directory(s.c_str())){
- throw interprocess_exception(error_info(system_error_code()));
- }
- s += "/";
- s += file_prefix;
- if(creation_time){
- std::string sstamp;
- get_pid_creation_time_str(sstamp);
- s += sstamp;
- }
- else{
- pid_str_t pid_str;
- get_pid_str(pid_str, pid);
- s += pid_str;
- }
-}
-
-inline bool check_if_filename_complies_with_pid
- (const char *filename, const char *prefix, OS_process_id_t pid, std::string &file_suffix, bool creation_time = false)
-{
- //Check if filename complies with lock file name pattern
- std::string fname(filename);
- std::string fprefix(prefix);
- if(fname.size() <= fprefix.size()){
- return false;
- }
- fname.resize(fprefix.size());
- if(fname != fprefix){
- return false;
- }
-
- //If not our lock file, delete it if we can lock it
- fname = filename;
- fname.erase(0, fprefix.size());
- pid_str_t pid_str;
- get_pid_str(pid_str, pid);
- file_suffix = pid_str;
- if(creation_time){
- std::size_t p = fname.find('_');
- if (p == std::string::npos){
- return false;
- }
- std::string save_suffix(fname);
- fname.erase(p);
- fname.swap(file_suffix);
- bool ret = (file_suffix == fname);
- file_suffix.swap(save_suffix);
- return ret;
- }
- else{
- fname.swap(file_suffix);
- return (file_suffix == fname);
- }
-}
-
-} //file_locking_helpers
-
-namespace intermodule_singleton_helpers {
-
-const int GMemMarkToBeRemoved = -1;
-const int GMemNotPresent = -2;
-
-inline const char *get_lock_file_subdir_name()
-{ return "gmem"; }
-
-inline const char *get_lock_file_base_name()
-{ return "lck"; }
-
-inline void create_and_get_singleton_lock_file_path(std::string &s)
-{
- file_locking_helpers::create_tmp_subdir_and_get_pid_based_filepath
- (get_lock_file_subdir_name(), get_lock_file_base_name(), get_current_process_id(), s, true);
-}
-
-inline const char *get_shm_base_name()
-{ return "bip.gmem.shm."; }
-
-inline void get_shm_name(std::string &shm_name)
-{
- file_locking_helpers::get_pid_creation_time_str(shm_name);
- shm_name.insert(0, get_shm_base_name());
-}
-
-inline std::size_t get_shm_size()
-{ return 65536; }
-
-template<class ManagedShMem>
-struct managed_sh_dependant
-{
- static void apply_gmem_erase_logic(const char *filepath, const char *filename);
-
- static bool remove_old_gmem()
- {
- std::string refcstrRootDirectory;
- tmp_folder(refcstrRootDirectory);
- refcstrRootDirectory += "/";
- refcstrRootDirectory += get_lock_file_subdir_name();
- return for_each_file_in_dir(refcstrRootDirectory.c_str(), apply_gmem_erase_logic);
- }
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct managed_sh_dependant<windows_managed_global_memory>
-{
- static void apply_gmem_erase_logic(const char *, const char *){}
-
- static bool remove_old_gmem()
- { return true; }
-};
-
-
-struct locking_file_serial_id
-{
- int fd;
- unsigned long dwVolumeSerialNumber;
- unsigned long nFileIndexHigh;
- unsigned long nFileIndexLow;
- //This reference count counts the number of modules attached
- //to the shared memory and lock file. This serves to unlink
- //the locking file and shared memory when all modules are
- //done with the global memory (shared memory)
- volatile boost::uint32_t modules_attached_to_gmem_count;
-};
-
-inline bool lock_locking_file(int fd)
-{
- int ret = 0;
- while(ret != 0 && errno == EDEADLK){
- ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/);
- }
- return 0 == ret;
-}
-
-inline bool try_lock_locking_file(int fd)
-{
- return 0 == _locking(fd, _LK_NBLCK , 1);
-}
-
-inline int open_or_create_and_lock_file(const char *name)
-{
- permissions p;
- p.set_unrestricted();
- while(1){
- file_handle_t handle = create_or_open_file(name, read_write, p);
- int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
- if(fd < 0){
- close_file(handle);
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- _close(fd);
- return -1;
- }
- struct _stat s;
- if(0 == _stat(name, &s)){
- return fd;
- }
- else{
- _close(fd);
- }
- }
-}
-
-inline int try_open_and_lock_file(const char *name)
-{
- file_handle_t handle = open_existing_file(name, read_write);
- int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
- if(fd < 0){
- close_file(handle);
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- _close(fd);
- return -1;
- }
- return fd;
-}
-
-inline void close_lock_file(int fd)
-{ _close(fd); }
-
-inline bool is_valid_fd(int fd)
-{
- struct _stat s;
- return EBADF != _fstat(fd, &s);
-}
-
-inline bool is_normal_file(int fd)
-{
- if(_isatty(fd))
- return false;
- struct _stat s;
- if(0 != _fstat(fd, &s))
- return false;
- return 0 != (s.st_mode & _S_IFREG);
-}
-
-inline std::size_t get_size(int fd)
-{
- struct _stat s;
- if(0 != _fstat(fd, &s))
- return 0u;
- return (std::size_t)s.st_size;
-}
-
-inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
-{
- winapi::interprocess_by_handle_file_information info;
- if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
- return false;
- id.fd = fd;
- id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
- id.nFileIndexHigh = info.nFileIndexHigh;
- id.nFileIndexLow = info.nFileIndexLow;
- id.modules_attached_to_gmem_count = 1; //Initialize attached count
- return true;
-}
-
-inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
-{
- winapi::interprocess_by_handle_file_information info;
- if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
- return false;
-
- return id.dwVolumeSerialNumber == info.dwVolumeSerialNumber &&
- id.nFileIndexHigh == info.nFileIndexHigh &&
- id.nFileIndexLow == info.nFileIndexLow;
-}
-
-#else //UNIX
-
-struct locking_file_serial_id
-{
- int fd;
- dev_t st_dev;
- ino_t st_ino;
- //This reference count counts the number of modules attached
- //to the shared memory and lock file. This serves to unlink
- //the locking file and shared memory when all modules are
- //done with the global memory (shared memory)
- volatile boost::uint32_t modules_attached_to_gmem_count;
-};
-
-inline bool lock_locking_file(int fd)
-{
- int ret = 0;
- while(ret != 0 && errno != EINTR){
- struct flock lock;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- ret = fcntl (fd, F_SETLKW, &lock);
- }
- return 0 == ret;
-}
-
-inline bool try_lock_locking_file(int fd)
-{
- struct flock lock;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- return 0 == fcntl (fd, F_SETLK, &lock);
-}
-
-inline int open_or_create_and_lock_file(const char *name)
-{
- permissions p;
- p.set_unrestricted();
- while(1){
- int fd = create_or_open_file(name, read_write, p);
- if(fd < 0){
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- close(fd);
- return -1;
- }
- struct stat s;
- if(0 == stat(name, &s)){
- return fd;
- }
- else{
- close(fd);
- }
- }
-}
-
-inline int try_open_and_lock_file(const char *name)
-{
- int fd = open_existing_file(name, read_write);
- if(fd < 0){
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- close(fd);
- return -1;
- }
- return fd;
-}
-
-inline void close_lock_file(int fd)
-{ close(fd); }
-
-inline bool is_valid_fd(int fd)
-{
- struct stat s;
- return EBADF != fstat(fd, &s);
-}
-
-inline bool is_normal_file(int fd)
-{
- struct stat s;
- if(0 != fstat(fd, &s))
- return false;
- return 0 != (s.st_mode & S_IFREG);
-}
-
-inline std::size_t get_size(int fd)
-{
- struct stat s;
- if(0 != fstat(fd, &s))
- return 0u;
- return (std::size_t)s.st_size;
-}
-
-inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
-{
- struct stat s;
- if(0 != fstat(fd, &s))
- return false;
- id.fd = fd;
- id.st_dev = s.st_dev;
- id.st_ino = s.st_ino;
- id.modules_attached_to_gmem_count = 1; //Initialize attached count
- return true;
-}
-
-inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
-{
- struct stat info;
- if(0 != fstat(fd, &info))
- return false;
-
- return id.st_dev == info.st_dev &&
- id.st_ino == info.st_ino;
-}
-
-#endif
-
-template<class ManagedShMem>
-struct gmem_erase_func
-{
- gmem_erase_func(const char *shm_name, const char *singleton_lock_file_path, ManagedShMem & shm)
- :shm_name_(shm_name), singleton_lock_file_path_(singleton_lock_file_path), shm_(shm)
- {}
-
- void operator()()
- {
- locking_file_serial_id *pserial_id = shm_.template find<locking_file_serial_id>("lock_file_fd").first;
- if(pserial_id){
- pserial_id->fd = GMemMarkToBeRemoved;
- }
- delete_file(singleton_lock_file_path_);
- shared_memory_object::remove(shm_name_);
- }
-
- const char * const shm_name_;
- const char * const singleton_lock_file_path_;
- ManagedShMem & shm_;
-};
-
-//This function applies shared memory erasure logic based on the passed lock file.
-template<class ManagedShMem>
-void managed_sh_dependant<ManagedShMem>::
- apply_gmem_erase_logic(const char *filepath, const char *filename)
-{
- int fd = GMemMarkToBeRemoved;
- try{
- std::string str;
- //If the filename is current process lock file, then avoid it
- if(file_locking_helpers::check_if_filename_complies_with_pid
- (filename, get_lock_file_base_name(), get_current_process_id(), str, true)){
- return;
- }
- //Open and lock the other process' lock file
- fd = try_open_and_lock_file(filepath);
- if(fd < 0){
- return;
- }
- //If done, then the process is dead so take global shared memory name
- //(the name is based on the lock file name) and try to apply erasure logic
- str.insert(0, get_shm_base_name());
- try{
- ManagedShMem shm(open_only, str.c_str());
- gmem_erase_func<ManagedShMem> func(str.c_str(), filepath, shm);
- shm.try_atomic_func(func);
- }
- catch(interprocess_exception &e){
- //If shared memory is not found erase the lock file
- if(e.get_error_code() == not_found_error){
- delete_file(filepath);
- }
- }
- }
- catch(...){
-
- }
- if(fd >= 0){
- close_lock_file(fd);
- }
-}
-
-} //namespace intermodule_singleton_helpers {
-
-
-
-namespace intermodule_singleton_helpers {
-
-//The lock file logic creates uses a unique instance to a file
-template <class ManagedShMem>
-struct lock_file_logic
-{
- lock_file_logic(ManagedShMem &shm)
- : mshm(shm)
- { shm.atomic_func(*this); }
-
- void operator()(void)
- {
- retry_with_new_shm = false;
-
- //First find the file locking descriptor id
- locking_file_serial_id *pserial_id =
- mshm.template find<locking_file_serial_id>("lock_file_fd").first;
-
- int fd;
- //If not found schedule a creation
- if(!pserial_id){
- fd = GMemNotPresent;
- }
- //Else get it
- else{
- fd = pserial_id->fd;
- }
- //If we need to create a new one, do it
- if(fd == GMemNotPresent){
- std::string lck_str;
- //Create a unique current pid based lock file path
- create_and_get_singleton_lock_file_path(lck_str);
- //Open or create and lock file
- int fd = intermodule_singleton_helpers::open_or_create_and_lock_file(lck_str.c_str());
- //If failed, write a bad file descriptor to notify other modules that
- //something was wrong and unlink shared memory. Mark the function object
- //to tell caller to retry with another shared memory
- if(fd < 0){
- this->register_lock_file(GMemMarkToBeRemoved);
- std::string s;
- get_shm_name(s);
- shared_memory_object::remove(s.c_str());
- retry_with_new_shm = true;
- }
- //If successful, register the file descriptor
- else{
- this->register_lock_file(fd);
- }
- }
- //If the fd was invalid (maybe a previous try failed) notify caller that
- //should retry creation logic, since this shm might have been already
- //unlinked since the shm was removed
- else if (fd == GMemMarkToBeRemoved){
- retry_with_new_shm = true;
- }
- //If the stored fd is not valid (a open fd, a normal file with the
- //expected size, or does not have the same file id number,
- //then it's an old shm from an old process with the same pid.
- //If that's the case, mark it as invalid
- else if(!is_valid_fd(fd) ||
- !is_normal_file(fd) ||
- 0 != get_size(fd) ||
- !compare_file_serial(fd, *pserial_id)){
- pserial_id->fd = GMemMarkToBeRemoved;
- std::string s;
- get_shm_name(s);
- shared_memory_object::remove(s.c_str());
- retry_with_new_shm = true;
- }
- else{
- //If the lock file is ok, increment reference count of
- //attached modules to shared memory
- atomic_inc32(&pserial_id->modules_attached_to_gmem_count);
- }
- }
-
- private:
- locking_file_serial_id * register_lock_file(int fd)
- {
- locking_file_serial_id *pinfo = mshm.template construct<locking_file_serial_id>("lock_file_fd")();
- fill_file_serial_id(fd, *pinfo);
- return pinfo;
- }
-
- public:
- ManagedShMem &mshm;
- bool retry_with_new_shm;
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct lock_file_logic<windows_managed_global_memory>
-{
- lock_file_logic(windows_managed_global_memory &)
- : retry_with_new_shm(false)
- {}
-
- void operator()(void){}
- const bool retry_with_new_shm;
-};
-
-#endif
-
-} //namespace intermodule_singleton_helpers {
-
-//This class contains common code for all singleton types, so that we instantiate this
-//code just once per module. This class also holds a reference counted shared memory
-//to be used by all instances
-
-template<class ManagedShMem>
-class intermodule_singleton_common
-{
- public:
- typedef void*(singleton_constructor_t)(ManagedShMem &);
- typedef void (singleton_destructor_t)(void *, ManagedShMem &);
-
- static const ::boost::uint32_t Uninitialized = 0u;
- static const ::boost::uint32_t Initializing = 1u;
- static const ::boost::uint32_t Initialized = 2u;
- static const ::boost::uint32_t Broken = 3u;
-
- static void finalize_singleton_logic(void *ptr, singleton_destructor_t destructor)
- {
- if(ptr)
- destructor(ptr, get_shm());
- //If this is the last singleton of this module
- //apply shm destruction.
- //Note: singletons are destroyed when the module is unloaded
- //so no threads should be executing or holding references
- //to this module
- if(1 == atomic_dec32(&this_module_singleton_count)){
- destroy_shm();
- }
- }
-
- static void initialize_singleton_logic
- (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t ini_func);
-
- private:
- static ManagedShMem &get_shm()
- {
- return *static_cast<ManagedShMem *>(static_cast<void *>(&mem_holder.shm_mem));
- }
-
- static void initialize_shm();
- static void destroy_shm();
- //Static data, zero-initalized without any dependencies
- //this_module_singleton_count is the number of singletons used by this module
- static volatile boost::uint32_t this_module_singleton_count;
- //this_module_shm_initialized is the state of this module's shm class object
- static volatile boost::uint32_t this_module_shm_initialized;
- static struct mem_holder_t
- {
- ::boost::detail::max_align aligner;
- char shm_mem [sizeof(ManagedShMem)];
- } mem_holder;
-};
-
-template<class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_singleton_count;
-
-template<class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_shm_initialized;
-
-template<class ManagedShMem>
-typename intermodule_singleton_common<ManagedShMem>::mem_holder_t
- intermodule_singleton_common<ManagedShMem>::mem_holder;
-
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::initialize_shm()
-{
- //Obtain unique shm name and size
- std::string s;
- while(1){
- //Try to pass shm state to initializing
- ::boost::uint32_t tmp = atomic_cas32(&this_module_shm_initialized, Initializing, Uninitialized);
- if(tmp >= Initialized){
- break;
- }
- //If some other thread is doing the work wait
- else if(tmp == Initializing){
- thread_yield();
- }
- else{ //(tmp == Uninitialized)
- //If not initialized try it again?
- try{
- //Remove old shared memory from the system
- intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::remove_old_gmem();
- //
- if(s.empty()){
- intermodule_singleton_helpers::get_shm_name(s);
- }
- const char *ShmName = s.c_str();
- const std::size_t ShmSize = intermodule_singleton_helpers::get_shm_size();;
-
- //in-place construction of the shared memory class
- ::new (&get_shm())ManagedShMem(open_or_create, ShmName, ShmSize);
- //Use shared memory internal lock to initialize the lock file
- //that will mark this gmem as "in use".
- intermodule_singleton_helpers::lock_file_logic<ManagedShMem> f(get_shm());
- //If function failed (maybe a competing process has erased the shared
- //memory between creation and file locking), retry with a new instance.
- if(f.retry_with_new_shm){
- get_shm().~ManagedShMem();
- atomic_write32(&this_module_shm_initialized, Uninitialized);
- }
- else{
- //Locking succeeded, so this shared memory module-instance is ready
- atomic_write32(&this_module_shm_initialized, Initialized);
- break;
- }
- }
- catch(...){
- //
- throw;
- }
- }
- }
-}
-
-template<class ManagedShMem>
-struct unlink_shmlogic
-{
- unlink_shmlogic(ManagedShMem &mshm)
- : mshm_(mshm)
- { mshm.atomic_func(*this); }
- void operator()()
- {
- intermodule_singleton_helpers::locking_file_serial_id *pserial_id =
- mshm_.template find<intermodule_singleton_helpers::locking_file_serial_id>
- ("lock_file_fd").first;
- BOOST_ASSERT(0 != pserial_id);
- if(1 == atomic_dec32(&pserial_id->modules_attached_to_gmem_count)){
- int fd = pserial_id->fd;
- if(fd > 0){
- pserial_id->fd = intermodule_singleton_helpers::GMemMarkToBeRemoved;
- std::string s;
- intermodule_singleton_helpers::create_and_get_singleton_lock_file_path(s);
- delete_file(s.c_str());
- intermodule_singleton_helpers::close_lock_file(fd);
- intermodule_singleton_helpers::get_shm_name(s);
- shared_memory_object::remove(s.c_str());
- }
- }
- }
- ManagedShMem &mshm_;
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct unlink_shmlogic<windows_managed_global_memory>
-{
- unlink_shmlogic(windows_managed_global_memory &)
- {}
- void operator()(){}
-};
-
-#endif
-
-
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::destroy_shm()
-{
- if(!atomic_read32(&this_module_singleton_count)){
- //This module is being unloaded, so destroy
- //the shared memory object of this module
- //and unlink the shared memory if it's the last
- unlink_shmlogic<ManagedShMem> f(get_shm());
- (get_shm()).~ManagedShMem();
- atomic_write32(&this_module_shm_initialized, Uninitialized);
- //Do some cleanup for other processes old gmem instances
- intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::remove_old_gmem();
- }
-}
-
-//Initialize this_module_singleton_ptr, creates the shared memory if needed and also creates an unique
-//opaque type in shared memory through a singleton_constructor_t function call,
-//initializing the passed pointer to that unique instance.
-//
-//We have two concurrency types here. a)the shared memory/singleton creation must
-//be safe between threads of this process but in different modules/dlls. b)
-//the pointer to the singleton is per-module, so we have to protect this
-//initization between threads of the same module.
-//
-//All static variables declared here are shared between inside a module
-//so atomic operations will synchronize only threads of the same module.
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
- (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t constructor)
-{
- //If current module is not initialized enter to lock free logic
- if(atomic_read32(&this_module_singleton_initialized) != Initialized){
- //Now a single thread of the module will succeed in this CAS.
- //trying to pass from Uninitialized to Initializing
- ::boost::uint32_t previous_module_singleton_initialized = atomic_cas32
- (&this_module_singleton_initialized, Initializing, Uninitialized);
- //If the thread succeeded the CAS (winner) it will compete with other
- //winner threads from other modules to create the shared memory
- if(previous_module_singleton_initialized == Uninitialized){
- try{
- //Now initialize shm, this function solves concurrency issues
- //between threads of several modules
- initialize_shm();
- //Increment the module reference count that reflects how many
- //singletons this module holds, so that we can safely destroy
- //module shared memory object when no singleton is left
- atomic_inc32(&this_module_singleton_count);
- //Now try to create the singleton in shared memory.
- //This function solves concurrency issues
- //between threads of several modules
- void *tmp = constructor(get_shm());
- //Insert a barrier before assigning the pointer to
- //make sure this assignment comes after the initialization
- atomic_write32(&this_module_singleton_initialized, Initializing);
- //Assign the singleton address to the module-local pointer
- ptr = tmp;
- //Memory barrier inserted, all previous operations should complete
- //before this one. Now marked as initialized
- atomic_inc32(&this_module_singleton_initialized);
- }
- catch(...){
- //Mark singleton failed to initialize
- atomic_write32(&this_module_singleton_initialized, Broken);
- throw;
- }
- }
- //If previous state was initializing, this means that another winner thread is
- //trying to initialize the singleton. Just wait until completes its work.
- else if(previous_module_singleton_initialized == Initializing){
- while(1){
- previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
- if(previous_module_singleton_initialized >= Initialized){
- //Already initialized, or exception thrown by initializer thread
- break;
- }
- else if(previous_module_singleton_initialized == Initializing){
- thread_yield();
- }
- else{
- //This can't be happening!
- BOOST_ASSERT(0);
- }
- }
- }
- else if(previous_module_singleton_initialized == Initialized){
- //Nothing to do here, the singleton is ready
- }
- //If previous state was greater than initialized, then memory is broken
- //trying to initialize the singleton.
- else{//(previous_module_singleton_initialized > Initialized)
- throw interprocess_exception("boost::interprocess::intermodule_singleton initialization failed");
- }
- }
- BOOST_ASSERT(ptr != 0);
-}
-
-//Now this class is a singleton, initializing the singleton in
-//the first get() function call if LazyInit is false. If true
-//then the singleton will be initialized when loading the module.
-template<typename C, bool LazyInit, class ManagedShMem>
-class intermodule_singleton_impl
-{
- public:
- static C& get() //Let's make inlining easy
- {
- if(!this_module_singleton_ptr){
- if(lifetime.dummy_function()) //This forces lifetime instantiation, for reference counted destruction
- intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
- (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
- }
- return *static_cast<C*>(this_module_singleton_ptr);
- }
-
- private:
-
- struct ref_count_ptr
- {
- ref_count_ptr(C *p, boost::uint32_t count)
- : ptr(p), singleton_ref_count(count)
- {}
- C *ptr;
- //This reference count serves to count the number of attached
- //modules to this singleton
- volatile boost::uint32_t singleton_ref_count;
- };
-
- //These statics will be zero-initialized without any constructor call dependency
- //this_module_singleton_ptr will be a module-local pointer to the singleton
- static void* this_module_singleton_ptr;
- //this_module_singleton_count will be used to synchronize threads of the same module
- //for access to a singleton instance, and to flag the state of the
- //singleton.
- static volatile boost::uint32_t this_module_singleton_initialized;
-
- //This class destructor will trigger singleton destruction
- struct lifetime_type_lazy
- {
- bool dummy_function()
- { return m_dummy == 0; }
-
- ~lifetime_type_lazy()
- {
- intermodule_singleton_common<ManagedShMem>::finalize_singleton_logic
- (this_module_singleton_ptr, singleton_destructor);
- }
- //Dummy volatile so that the compiler can't resolve its value at compile-time
- //and can't avoid lifetime_type instantiation if dummy_function() is called.
- static volatile int m_dummy;
- };
-
- struct lifetime_type_static
- : public lifetime_type_lazy
- {
- lifetime_type_static()
- {
- intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
- (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
- }
- };
-
- typedef typename if_c
- <LazyInit, lifetime_type_lazy, lifetime_type_static>::type lifetime_type;
-
- static lifetime_type lifetime;
-
- //A functor to be executed inside shared memory lock that just
- //searches for the singleton in shm and if not present creates a new one.
- //If singleton constructor throws, the exception is propagated
- struct init_atomic_func
- {
- init_atomic_func(ManagedShMem &m)
- : mshm(m)
- {}
-
- void operator()()
- {
- ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
- if(!rcount){
- C *p = new C();
- try{
- rcount = mshm.template construct<ref_count_ptr>(unique_instance)(p, 0u);
- }
- catch(...){
- delete p;
- throw;
- }
- }
- atomic_inc32(&rcount->singleton_ref_count);
- ret_ptr = rcount->ptr;
- }
- ManagedShMem &mshm;
- void *ret_ptr;
- };
-
- //A functor to be executed inside shared memory lock that just
- //deletes the singleton in shm if the attached count reaches to zero
- struct fini_atomic_func
- {
- fini_atomic_func(ManagedShMem &m)
- : mshm(m)
- {}
-
- void operator()()
- {
- ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
- //The object must exist
- BOOST_ASSERT(rcount);
- //Check if last reference
- if(atomic_dec32(&rcount->singleton_ref_count) == 1){
- //If last, destroy the object
- BOOST_ASSERT(rcount->ptr != 0);
- delete rcount->ptr;
- //Now destroy shm entry
- bool destroyed = mshm.template destroy<ref_count_ptr>(unique_instance);
- (void)destroyed; BOOST_ASSERT(destroyed == true);
- }
- }
- ManagedShMem &mshm;
- void *ret_ptr;
- };
-
- //A wrapper to execute init_atomic_func
- static void *singleton_constructor(ManagedShMem &mshm)
- {
- init_atomic_func f(mshm);
- mshm.atomic_func(f);
- return f.ret_ptr;
- }
-
- //A wrapper to execute fini_atomic_func
- static void singleton_destructor(void *p, ManagedShMem &mshm)
- { (void)p;
- fini_atomic_func f(mshm);
- mshm.atomic_func(f);
- }
-};
-
-template <typename C, bool L, class ManagedShMem>
-volatile int intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type_lazy::m_dummy = 0;
-
-//These will be zero-initialized by the loader
-template <typename C, bool L, class ManagedShMem>
-void *intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_ptr = 0;
-
-template <typename C, bool L, class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_initialized = 0;
-
-template <typename C, bool L, class ManagedShMem>
-typename intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type
- intermodule_singleton_impl<C, L, ManagedShMem>::lifetime;
-
-template<typename C, bool LazyInit = false>
-class portable_intermodule_singleton
- : public intermodule_singleton_impl<C, LazyInit, managed_global_memory>
-{};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<typename C, bool LazyInit = false>
-class windows_intermodule_singleton
- : public intermodule_singleton_impl
- < C
- , LazyInit
- , windows_managed_global_memory
- >
-{};
-
-#endif
-
//Now this class is a singleton, initializing the singleton in
//the first get() function call if LazyInit is false. If true
//then the singleton will be initialized when loading the module.
@@ -1174,7 +39,6 @@
#endif
{};
-
} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
Modified: branches/release/boost/interprocess/detail/os_file_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_file_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/os_file_functions.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -140,7 +140,7 @@
if(offset_t(size) > filesize){
if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
return false;
- }
+ }
//We will write zeros in the end of the file
//since set_end_of_file does not guarantee this
for(std::size_t remaining = size - filesize, write_size = 0
@@ -191,7 +191,7 @@
inline bool acquire_file_lock(file_handle_t hnd)
{
static winapi::interprocess_overlapped overlapped;
- const unsigned long len = 0xffffffff;
+ const unsigned long len = ~((unsigned long)(0u));
// winapi::interprocess_overlapped overlapped;
// std::memset(&overlapped, 0, sizeof(overlapped));
return winapi::lock_file_ex
@@ -200,7 +200,7 @@
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
{
- const unsigned long len = 0xffffffff;
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
if(!winapi::lock_file_ex
@@ -215,7 +215,7 @@
inline bool release_file_lock(file_handle_t hnd)
{
- const unsigned long len = 0xffffffff;
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return winapi::unlock_file_ex(hnd, 0, len, len, &overlapped);
@@ -223,7 +223,7 @@
inline bool acquire_file_lock_sharable(file_handle_t hnd)
{
- const unsigned long len = 0xffffffff;
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return winapi::lock_file_ex(hnd, 0, 0, len, len, &overlapped);
@@ -231,7 +231,7 @@
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
{
- const unsigned long len = 0xffffffff;
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
if(!winapi::lock_file_ex
Modified: branches/release/boost/interprocess/detail/pointer_type.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/pointer_type.hpp (original)
+++ branches/release/boost/interprocess/detail/pointer_type.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -61,7 +61,7 @@
struct pointer_type
{
typedef typename pointer_type_imp::pointer_type<T,
- typename ipcdetail::remove_reference<D>::type>::type type;
+ typename remove_reference<D>::type>::type type;
};
} //namespace ipcdetail {
Modified: branches/release/boost/interprocess/detail/preprocessor.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/preprocessor.hpp (original)
+++ branches/release/boost/interprocess/detail/preprocessor.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -57,28 +57,30 @@
#ifndef BOOST_NO_RVALUE_REFERENCES
-#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (BOOST_INTERPROCESS_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
-//!
+ #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
+ //!
-#else
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
-//!
+ #else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-#endif
+ #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
+ //!
-#else
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
-//!
+ #endif //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#else //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+ #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
+ //!
#endif
#define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data) \
- BOOST_PP_CAT(++m_p, n) \
+ BOOST_PP_CAT(++m_p, n) \
//!
#ifndef BOOST_NO_RVALUE_REFERENCES
Modified: branches/release/boost/interprocess/detail/robust_emulation.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/robust_emulation.hpp (original)
+++ branches/release/boost/interprocess/detail/robust_emulation.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -68,7 +68,7 @@
inline void create_and_get_robust_lock_file_path(std::string &s, OS_process_id_t pid)
{
- file_locking_helpers::create_tmp_subdir_and_get_pid_based_filepath
+ intermodule_singleton_helpers::create_tmp_subdir_and_get_pid_based_filepath
(robust_lock_subdir_path(), robust_lock_prefix(), pid, s);
}
@@ -154,7 +154,7 @@
{
std::string pid_str;
//If the lock file is not our own lock file, then try to do the cleanup
- if(!file_locking_helpers::check_if_filename_complies_with_pid
+ if(!intermodule_singleton_helpers::check_if_filename_complies_with_pid
(filename, robust_lock_prefix(), get_current_process_id(), pid_str)){
remove_if_can_lock_file(filepath);
}
Modified: branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp (original)
+++ branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -18,80 +18,87 @@
#include <boost/interprocess/exceptions.hpp>
#include <string>
-#if defined(BOOST_INTERPROCESS_WINDOWS)
- //#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
- //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- //#include <boost/interprocess/detail/win32_api.hpp>
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
- //#include <sys/sysctl.h>
- //#if defined(CTL_KERN) && defined (KERN_BOOTTIME)
- //#define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
- //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- //#endif
+#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) && defined(BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#endif
namespace boost {
namespace interprocess {
namespace ipcdetail {
-#if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
-inline void get_bootstamp(std::string &s, bool add = false)
-{
- std::string bootstamp;
- winapi::get_last_bootup_time(bootstamp);
- if(add){
- s += bootstamp;
- }
- else{
- s.swap(bootstamp);
- }
-}
-#elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
-inline void get_bootstamp(std::string &s, bool add = false)
-{
- // FreeBSD specific: sysctl "kern.boottime"
- int request[2] = { CTL_KERN, KERN_BOOTTIME };
- struct ::timeval result;
- std::size_t result_len = sizeof result;
-
- if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
- return;
-
- char bootstamp_str[256];
-
- const char Characters [] =
- { '0', '1', '2', '3', '4', '5', '6', '7'
- , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
- std::size_t char_counter = 0;
- //32 bit values to allow 32 and 64 bit process IPC
- boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
- for(std::size_t field = 0; field != 2; ++field){
- for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
- const char *ptr = (const char *)&fields[field];
- bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
- bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
+#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+ #if defined(BOOST_INTERPROCESS_WINDOWS)
+ //This type will initialize the stamp
+ struct windows_bootstamp
+ {
+ windows_bootstamp()
+ {
+ winapi::get_last_bootup_time(stamp);
+ }
+ //Use std::string. Even if this will be constructed in shared memory, all
+ //modules/dlls are from this process so internal raw pointers to heap are always valid
+ std::string stamp;
+ };
+
+ inline void get_bootstamp(std::string &s, bool add = false)
+ {
+ const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp, true>::get();
+ if(add){
+ s += bootstamp.stamp;
+ }
+ else{
+ s = bootstamp.stamp;
+ }
}
- }
- bootstamp_str[char_counter] = 0;
- if(add){
- s += bootstamp_str;
- }
- else{
- s = bootstamp_str;
- }
-}
-#endif
+ #elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
+ inline void get_bootstamp(std::string &s, bool add = false)
+ {
+ // FreeBSD specific: sysctl "kern.boottime"
+ int request[2] = { CTL_KERN, KERN_BOOTTIME };
+ struct ::timeval result;
+ std::size_t result_len = sizeof result;
+
+ if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
+ return;
+
+ char bootstamp_str[256];
+
+ const char Characters [] =
+ { '0', '1', '2', '3', '4', '5', '6', '7'
+ , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ std::size_t char_counter = 0;
+ //32 bit values to allow 32 and 64 bit process IPC
+ boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
+ for(std::size_t field = 0; field != 2; ++field){
+ for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
+ const char *ptr = (const char *)&fields[field];
+ bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
+ bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
+ }
+ }
+ bootstamp_str[char_counter] = 0;
+ if(add){
+ s += bootstamp_str;
+ }
+ else{
+ s = bootstamp_str;
+ }
+ }
+ #else
+ #error "BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME defined with no known implementation"
+ #endif
+#endif //#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
inline void get_tmp_base_dir(std::string &tmp_name)
{
#if defined (BOOST_INTERPROCESS_WINDOWS)
- winapi::get_shared_documents_folder(tmp_name);
- if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
- tmp_name = get_temporary_path();
- }
+ winapi::get_shared_documents_folder(tmp_name);
+ if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
+ tmp_name = get_temporary_path();
+ }
#else
- tmp_name = get_temporary_path();
+ tmp_name = get_temporary_path();
#endif
if(tmp_name.empty()){
error_info err = system_error_code();
@@ -104,9 +111,9 @@
inline void tmp_folder(std::string &tmp_name)
{
get_tmp_base_dir(tmp_name);
- #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- tmp_name += "/";
- get_bootstamp(tmp_name, true);
+ #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+ tmp_name += "/";
+ get_bootstamp(tmp_name, true);
#endif
}
@@ -131,22 +138,22 @@
}
}
- #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- tmp_folder(tmp_name);
+ #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+ tmp_folder(tmp_name);
- //If fails, check that it's because already exists
- if(!create_directory(tmp_name.c_str())){
- error_info info(system_error_code());
- if(info.get_error_code() != already_exists_error){
- throw interprocess_exception(info);
+ //If fails, check that it's because already exists
+ if(!create_directory(tmp_name.c_str())){
+ error_info info(system_error_code());
+ if(info.get_error_code() != already_exists_error){
+ throw interprocess_exception(info);
+ }
}
- }
- //Now erase all old directories created in the previous boot sessions
- std::string subdir = tmp_name;
- subdir.erase(0, root_tmp_name.size()+1);
- delete_subdirectories(root_tmp_name, subdir.c_str());
+ //Now erase all old directories created in the previous boot sessions
+ std::string subdir = tmp_name;
+ subdir.erase(0, root_tmp_name.size()+1);
+ delete_subdirectories(root_tmp_name, subdir.c_str());
#else
- tmp_name = root_tmp_name;
+ tmp_name = root_tmp_name;
#endif
}
Modified: branches/release/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/win32_api.hpp (original)
+++ branches/release/boost/interprocess/detail/win32_api.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -574,6 +574,12 @@
void *h_event;
};
+struct interprocess_semaphore_basic_information
+{
+ unsigned int count; // current semaphore count
+ unsigned int limit; // max semaphore count
+};
+
struct interprocess_filetime
{
unsigned long dwLowDateTime;
@@ -620,7 +626,7 @@
unsigned short wProcessorRevision;
};
-struct interprocess_memory_basic_information
+typedef struct _interprocess_memory_basic_information
{
void * BaseAddress;
void * AllocationBase;
@@ -629,7 +635,7 @@
unsigned long State;
unsigned long Protect;
unsigned long Type;
-};
+} interprocess_memory_basic_information;
typedef struct _interprocess_acl
{
@@ -695,6 +701,10 @@
file_maximum_information
};
+enum semaphore_information_class {
+ semaphore_basic_information = 0
+};
+
struct file_name_information_t {
unsigned long FileNameLength;
wchar_t FileName[1];
@@ -844,6 +854,7 @@
extern "C" __declspec(dllimport) int __stdcall LockFileEx(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped);
+extern "C" __declspec(dllimport) int __stdcall ReadFile(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision);
extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted);
extern "C" __declspec(dllimport) void *__stdcall LoadLibraryA(const char *);
@@ -891,8 +902,9 @@
//Pointer to functions
typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
-typedef long (__stdcall * NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
-typedef long (__stdcall * NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
+typedef long (__stdcall *NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
+typedef long (__stdcall *NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
+typedef long (__stdcall *NtQuerySemaphore_t)(void*, unsigned int info_class, interprocess_semaphore_basic_information *pinfo, unsigned int info_size, unsigned int *ret_len);
typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
typedef long (__stdcall *NtClose_t) (void*);
@@ -1051,7 +1063,7 @@
if (error_sharing_violation != get_last_error()){
return handle;
}
- Sleep(error_sharing_violation_sleep_ms);
+ sleep(error_sharing_violation_sleep_ms);
}
return invalid_handle_value;
}
@@ -1101,6 +1113,9 @@
inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
{ return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped); }
+inline bool read_file(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped)
+{ return 0 != ReadFile(hnd, buffer, bytes_to_read, bytes_read, overlapped); }
+
inline bool get_file_information_by_handle(void *hnd, interprocess_by_handle_file_information *info)
{ return 0 != GetFileInformationByHandle(hnd, info); }
@@ -1176,7 +1191,7 @@
template<int Dummy>
struct function_address_holder
{
- enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NumFunction };
+ enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NumFunction };
enum { NtDll_dll, NumModule };
private:
@@ -1213,7 +1228,7 @@
static void *get_address_from_dll(const unsigned int id)
{
assert(id < (unsigned int)NumFunction);
- const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject" };
+ const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject", "NtQuerySemaphore" };
bool compile_check[sizeof(function)/sizeof(function[0]) == NumFunction];
(void)compile_check;
return get_proc_address(get_module(NtDll_dll), function[id]);
Modified: branches/release/boost/interprocess/detail/workaround.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/workaround.hpp (original)
+++ branches/release/boost/interprocess/detail/workaround.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -13,42 +13,33 @@
#include <boost/interprocess/detail/config_begin.hpp>
-#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
-
-#define BOOST_INTERPROCESS_WINDOWS
-
-/*
-#if !defined(_MSC_EXTENSIONS)
-#error "Turn on Microsoft language extensions (_MSC_EXTENSIONS) to be able to call Windows API functions"
-#endif
-*/
-
-#endif
-
-#if !defined(BOOST_INTERPROCESS_WINDOWS)
-
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ #define BOOST_INTERPROCESS_WINDOWS
+ //#define BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION
+ #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
+#else
#include <unistd.h>
- #if ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
- //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
- //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
- # if !defined(__CYGWIN__) && !defined(__APPLE__)
- # define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
- # endif
+ #if defined(_POSIX_THREAD_PROCESS_SHARED) && ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
+ //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
+ //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
+ #if !defined(__CYGWIN__) && !defined(__APPLE__)
+ #define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
+ #endif
#endif
- #if ((_POSIX_BARRIERS - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_BARRIERS
- # endif
-
- #if ((_POSIX_SEMAPHORES - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
- # if defined(__CYGWIN__)
- #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
- # endif
+ #if defined(_POSIX_BARRIERS) && ((_POSIX_BARRIERS - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_BARRIERS
+ #endif
+
+ #if defined(_POSIX_SEMAPHORES) && ((_POSIX_SEMAPHORES - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
+ #if defined(__CYGWIN__)
+ #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
+ #endif
//Some platforms have a limited (name length) named semaphore support
#elif (defined(__FreeBSD__) && (__FreeBSD__ >= 4)) || defined(__APPLE__)
- # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
+ #define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
#endif
#if ((defined _V6_ILP32_OFFBIG) &&(_V6_ILP32_OFFBIG - 0 > 0)) ||\
@@ -60,87 +51,83 @@
((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS - 0 >= 64))||\
((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS - 0 >= 64))
#define BOOST_INTERPROCESS_UNIX_64_BIT_OR_BIGGER_OFF_T
- #else
#endif
//Check for XSI shared memory objects. They are available in nearly all UNIX platforms
#if !defined(__QNXNTO__)
- # define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+ #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
#endif
- #if ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ #if defined(_POSIX_SHARED_MEMORY_OBJECTS) && ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
#else
- //VMS and MACOS don't define it but the have shm_open/close interface
- # if defined(__vms)
- # if __CRTL_VER >= 70200000
- # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
- # endif
- //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
- # elif defined (__APPLE__)
-// # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
-// # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
- # endif
+ //VMS and MACOS don't define it but they have shm_open/close interface
+ #if defined(__vms)
+ #if __CRTL_VER >= 70200000
+ #define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ #endif
+ //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
+ #elif defined (__APPLE__)
+ //#define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ //#define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
+ #endif
#endif
//Now check if we have only XSI shared memory
#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) &&\
!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
- //# define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY
+ //#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY
#endif
- #if ((_POSIX_TIMEOUTS - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ #if defined(_POSIX_TIMEOUTS) && ((_POSIX_TIMEOUTS - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_TIMEOUTS
#endif
-
#ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
//Some systems have filesystem-based resources, so the
//portable "/shmname" format does not work due to permission issues
//For those systems we need to form a path to a temporary directory:
// hp-ux tru64 vms freebsd
#if defined(__hpux) || defined(__osf__) || defined(__vms) || (defined(__FreeBSD__) && (__FreeBSD__ < 7))
- #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
+ #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
#elif defined(__FreeBSD__)
- #define BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
+ #define BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
#endif
#endif
#ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
#if defined(__osf__) || defined(__vms)
- #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
+ #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
#endif
#endif
- #if ((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500)
- #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
+ #if defined(_POSIX_VERSION) && defined(_XOPEN_VERSION) && \
+ (((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500))
+ #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
#endif
-#endif
+ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+ #define BOOST_INTERPROCESS_BSD_DERIVATIVE
+ #include <sys/sysctl.h>
+ #if defined(CTL_KERN) && defined (KERN_BOOTTIME)
+ //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
+ #endif
+ #endif
+#endif //!defined(BOOST_INTERPROCESS_WINDOWS)
-#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
- && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
-#define BOOST_INTERPROCESS_PERFECT_FORWARDING
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #define BOOST_INTERPROCESS_PERFECT_FORWARDING
#endif
//Now declare some Boost.Interprocess features depending on the implementation
-
-#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
-
-#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
-
-#endif
-
#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
-
-#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
-#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
-
+ #define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+ #define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
#endif
// Timeout duration use if BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING is set
#ifndef BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS
-#define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
+ #define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
#endif
#include <boost/interprocess/detail/config_end.hpp>
Modified: branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -28,7 +28,7 @@
#include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
#include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <functional> // std::less
Modified: branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -26,7 +26,7 @@
#include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -137,8 +137,13 @@
ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) );
}
+ //!Copy constructs a shared_ptr. If r is empty, constructs an empty shared_ptr. Otherwise, constructs
+ //!a shared_ptr that shares ownership with r. Never throws.
+ shared_ptr(const shared_ptr &r)
+ : m_pn(r.m_pn) // never throws
+ {}
- //!Constructs a shared_ptr that shares ownership with r and stores p.
+ //!Constructs a shared_ptr that shares ownership with other and stores p.
//!Postconditions: get() == p && use_count() == r.use_count().
//!Throws: nothing.
shared_ptr(const shared_ptr &other, const pointer &p)
Modified: branches/release/boost/interprocess/sync/interprocess_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_condition.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -30,9 +30,9 @@
#include <boost/interprocess/sync/posix/condition.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/condition.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/condition.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/condition.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: branches/release/boost/interprocess/sync/interprocess_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_mutex.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -31,9 +31,9 @@
#include <boost/interprocess/sync/posix/mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/mutex.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -43,9 +43,9 @@
#include <boost/interprocess/sync/posix/recursive_mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: branches/release/boost/interprocess/sync/interprocess_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_semaphore.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -29,9 +29,9 @@
#include <boost/interprocess/sync/posix/semaphore.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/semaphore.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/semaphore.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
Modified: branches/release/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/named_condition.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -22,7 +22,12 @@
#include <boost/interprocess/detail/interprocess_tester.hpp>
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/interprocess/sync/shm/named_condition.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_condition.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+ #include <boost/interprocess/sync/shm/named_condition.hpp>
+#endif
//!\file
//!Describes a named condition class for inter-process synchronization
@@ -110,7 +115,12 @@
/// @cond
private:
- ipcdetail::shm_named_condition m_cond;
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_condition condition_type;
+ #else
+ typedef ipcdetail::shm_named_condition condition_type;
+ #endif
+ condition_type m_cond;
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
@@ -160,7 +170,7 @@
{ return m_cond.timed_wait(lock, abs_time, pred); }
inline bool named_condition::remove(const char *name)
-{ return ipcdetail::shm_named_condition::remove(name); }
+{ return condition_type::remove(name); }
/// @endcond
Modified: branches/release/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/named_mutex.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -24,7 +24,11 @@
#include <boost/interprocess/permissions.hpp>
#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-#include <boost/interprocess/sync/posix/named_mutex.hpp>
+ #include <boost/interprocess/sync/posix/named_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#else
#include <boost/interprocess/sync/shm/named_mutex.hpp>
#endif
@@ -104,15 +108,20 @@
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_mutex impl_t;
- impl_t m_mut;
+ #if defined(BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES)
+ typedef ipcdetail::posix_named_mutex impl_t;
+ impl_t m_mut;
+ #undef BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_mutex impl_t;
+ impl_t m_mut;
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
#else
- typedef ipcdetail::shm_named_mutex impl_t;
- impl_t m_mut;
- public:
- interprocess_mutex *mutex() const
- { return m_mut.mutex(); }
+ typedef ipcdetail::shm_named_mutex impl_t;
+ impl_t m_mut;
+ public:
+ interprocess_mutex *mutex() const
+ { return m_mut.mutex(); }
#endif
/// @endcond
Modified: branches/release/boost/interprocess/sync/named_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/named_recursive_mutex.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -20,7 +20,12 @@
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/permissions.hpp>
-#include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_recursive_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+ #include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#endif
//!\file
//!Describes a named named_recursive_mutex class for inter-process synchronization
@@ -97,7 +102,12 @@
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- typedef ipcdetail::shm_named_recursive_mutex impl_t;
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_recursive_mutex impl_t;
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ #else
+ typedef ipcdetail::shm_named_recursive_mutex impl_t;
+ #endif
impl_t m_mut;
/// @endcond
Modified: branches/release/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/named_semaphore.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -25,6 +25,10 @@
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
#include <boost/interprocess/sync/posix/named_semaphore.hpp>
+//Experimental...
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#else
#include <boost/interprocess/sync/shm/named_semaphore.hpp>
#endif
@@ -106,9 +110,12 @@
void dont_close_on_destruction();
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_semaphore impl_t;
+ typedef ipcdetail::posix_named_semaphore impl_t;
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ typedef ipcdetail::windows_named_semaphore impl_t;
#else
- typedef ipcdetail::shm_named_semaphore impl_t;
+ typedef ipcdetail::shm_named_semaphore impl_t;
#endif
impl_t m_sem;
/// @endcond
Modified: branches/release/boost/interprocess/sync/shm/named_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/shm/named_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/shm/named_condition.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -28,7 +28,7 @@
#include <boost/interprocess/sync/shm/named_creation_functor.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/permissions.hpp>
-#if defined BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#endif
@@ -42,7 +42,7 @@
namespace ipcdetail {
/// @cond
-namespace ipcdetail{ class interprocess_tester; }
+class interprocess_tester;
/// @endcond
//! A global condition variable that can be created by name.
@@ -147,6 +147,9 @@
void unlock() { l_.lock(); }
};
+ //If named mutex uses POSIX semaphores, then the shm based condition variable
+ //must use it's internal lock to wait, as sem_t does not store a pthread_mutex_t
+ //instance needed by pthread_mutex_cond_t
#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
interprocess_mutex *mutex() const
{ return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
@@ -184,7 +187,7 @@
internal_lock.swap(internal_unlock);
return this->condition()->timed_wait(internal_unlock, abs_time);
}
- #else
+ #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
template<class Lock>
class lock_wrapper
{
@@ -210,7 +213,7 @@
private:
Lock &l_;
};
- #endif
+ #endif //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
friend class boost::interprocess::ipcdetail::interprocess_tester;
void dont_close_on_destruction();
Modified: branches/release/boost/interprocess/sync/windows/condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/windows/condition.hpp (original)
+++ branches/release/boost/interprocess/sync/windows/condition.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -20,133 +20,8 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/windows/semaphore.hpp>
#include <boost/interprocess/sync/windows/mutex.hpp>
-#include <boost/cstdint.hpp>
-#include <limits>
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// Condition variable algorithm taken from pthreads-win32 discussion.
-//
-// The algorithm was developed by Alexander Terekhov in colaboration with
-// Louis Thomas.
-//
-// Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
-//
-// semBlockLock - bin.semaphore
-// semBlockQueue - semaphore
-// mtxExternal - mutex or CS
-// mtxUnblockLock - mutex or CS
-// nWaitersGone - int
-// nWaitersBlocked - int
-// nWaitersToUnblock - int
-//
-// wait( timeout ) {
-//
-// [auto: register int result ] // error checking omitted
-// [auto: register int nSignalsWasLeft ]
-// [auto: register int nWaitersWasGone ]
-//
-// sem_wait( semBlockLock );
-// nWaitersBlocked++;
-// sem_post( semBlockLock );
-//
-// unlock( mtxExternal );
-// bTimedOut = sem_wait( semBlockQueue,timeout );
-//
-// lock( mtxUnblockLock );
-// if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
-// if ( bTimedOut ) { // timeout (or canceled)
-// if ( 0 != nWaitersBlocked ) {
-// nWaitersBlocked--;
-// }
-// else {
-// nWaitersGone++; // count spurious wakeups.
-// }
-// }
-// if ( 0 == --nWaitersToUnblock ) {
-// if ( 0 != nWaitersBlocked ) {
-// sem_post( semBlockLock ); // open the gate.
-// nSignalsWasLeft = 0; // do not open the gate
-// // below again.
-// }
-// else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-// nWaitersGone = 0;
-// }
-// }
-// }
-// else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
-// // spurious semaphore :-)
-// sem_wait( semBlockLock );
-// nWaitersBlocked -= nWaitersGone; // something is going on here
-// // - test of timeouts? :-)
-// sem_post( semBlockLock );
-// nWaitersGone = 0;
-// }
-// unlock( mtxUnblockLock );
-//
-// if ( 1 == nSignalsWasLeft ) {
-// if ( 0 != nWaitersWasGone ) {
-// // sem_adjust( semBlockQueue,-nWaitersWasGone );
-// while ( nWaitersWasGone-- ) {
-// sem_wait( semBlockQueue ); // better now than spurious later
-// }
-// } sem_post( semBlockLock ); // open the gate
-// }
-//
-// lock( mtxExternal );
-//
-// return ( bTimedOut ) ? ETIMEOUT : 0;
-// }
-//
-// signal(bAll) {
-//
-// [auto: register int result ]
-// [auto: register int nSignalsToIssue]
-//
-// lock( mtxUnblockLock );
-//
-// if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-// if ( 0 == nWaitersBlocked ) { // NO-OP
-// return unlock( mtxUnblockLock );
-// }
-// if (bAll) {
-// nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
-// nWaitersBlocked = 0;
-// }
-// else {
-// nSignalsToIssue = 1;
-// nWaitersToUnblock++;
-// nWaitersBlocked--;
-// }
-// }
-// else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-// sem_wait( semBlockLock ); // close the gate
-// if ( 0 != nWaitersGone ) {
-// nWaitersBlocked -= nWaitersGone;
-// nWaitersGone = 0;
-// }
-// if (bAll) {
-// nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
-// nWaitersBlocked = 0;
-// }
-// else {
-// nSignalsToIssue = nWaitersToUnblock = 1;
-// nWaitersBlocked--;
-// }
-// }
-// else { // NO-OP
-// return unlock( mtxUnblockLock );
-// }
-//
-// unlock( mtxUnblockLock );
-// sem_post( semBlockQueue,nSignalsToIssue );
-// return result;
-// }
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
namespace boost {
namespace interprocess {
@@ -156,6 +31,7 @@
{
windows_condition(const windows_condition &);
windows_condition &operator=(const windows_condition &);
+
public:
windows_condition();
~windows_condition();
@@ -217,162 +93,71 @@
private:
- template<class InterprocessMutex>
- bool do_timed_wait(bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
- void do_signal (bool broadcast);
+ struct condition_data
+ {
+ typedef boost::int32_t integer_type;
+ typedef windows_semaphore semaphore_type;
+ typedef windows_mutex mutex_type;
+
+ condition_data()
+ : m_nwaiters_blocked(0)
+ , m_nwaiters_gone(0)
+ , m_nwaiters_to_unblock(0)
+ , m_sem_block_queue(0)
+ , m_sem_block_lock(1)
+ , m_mtx_unblock_lock()
+ {}
+
+ integer_type &get_nwaiters_blocked()
+ { return m_nwaiters_blocked; }
+
+ integer_type &get_nwaiters_gone()
+ { return m_nwaiters_gone; }
+
+ integer_type &get_nwaiters_to_unblock()
+ { return m_nwaiters_to_unblock; }
+
+ semaphore_type &get_sem_block_queue()
+ { return m_sem_block_queue; }
+
+ semaphore_type &get_sem_block_lock()
+ { return m_sem_block_lock; }
+
+ mutex_type &get_mtx_unblock_lock()
+ { return m_mtx_unblock_lock; }
+
+ boost::int32_t m_nwaiters_blocked;
+ boost::int32_t m_nwaiters_gone;
+ boost::int32_t m_nwaiters_to_unblock;
+ windows_semaphore m_sem_block_queue;
+ windows_semaphore m_sem_block_lock;
+ windows_mutex m_mtx_unblock_lock;
+ } m_condition_data;
- boost::int32_t m_nwaiters_blocked;
- boost::int32_t m_nwaiters_gone;
- boost::int32_t m_nwaiters_to_unblock;
- windows_semaphore m_sem_block_queue;
- windows_semaphore m_sem_block_lock;
- windows_mutex m_mtx_unblock_lock;
+ typedef condition_algorithm_8a<condition_data> algorithm_type;
};
inline windows_condition::windows_condition()
- : m_nwaiters_blocked(0)
- , m_nwaiters_gone(0)
- , m_nwaiters_to_unblock(0)
- , m_sem_block_queue(0)
- , m_sem_block_lock(1)
- , m_mtx_unblock_lock()
+ : m_condition_data()
{}
inline windows_condition::~windows_condition()
{}
inline void windows_condition::notify_one()
-{ this->do_signal(false); }
+{ algorithm_type::signal(m_condition_data, false); }
inline void windows_condition::notify_all()
-{ this->do_signal(true); }
-
-inline void windows_condition::do_signal(bool broadcast)
-{
- boost::int32_t nsignals_to_issue;
-
- {
- scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
-
- if ( 0 != m_nwaiters_to_unblock ) { // the gate is closed!!!
- if ( 0 == m_nwaiters_blocked ) { // NO-OP
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- return;
- }
- if (broadcast) {
- m_nwaiters_to_unblock += nsignals_to_issue = m_nwaiters_blocked;
- m_nwaiters_blocked = 0;
- }
- else {
- nsignals_to_issue = 1;
- m_nwaiters_to_unblock++;
- m_nwaiters_blocked--;
- }
- }
- else if ( m_nwaiters_blocked > m_nwaiters_gone ) { // HARMLESS RACE CONDITION!
- m_sem_block_lock.wait(); // close the gate
- if ( 0 != m_nwaiters_gone ) {
- m_nwaiters_blocked -= m_nwaiters_gone;
- m_nwaiters_gone = 0;
- }
- if (broadcast) {
- nsignals_to_issue = m_nwaiters_to_unblock = m_nwaiters_blocked;
- m_nwaiters_blocked = 0;
- }
- else {
- nsignals_to_issue = m_nwaiters_to_unblock = 1;
- m_nwaiters_blocked--;
- }
- }
- else { // NO-OP
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- return;
- }
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- }
- m_sem_block_queue.post(nsignals_to_issue);
-}
+{ algorithm_type::signal(m_condition_data, true); }
template<class InterprocessMutex>
inline void windows_condition::do_wait(InterprocessMutex &mut)
-{ this->do_timed_wait(false, boost::posix_time::ptime(), mut); }
+{ algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut); }
template<class InterprocessMutex>
inline bool windows_condition::do_timed_wait
(const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
-{ return this->do_timed_wait(true, abs_time, mut); }
-
-template<class InterprocessMutex>
-inline bool windows_condition::do_timed_wait
- (bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
-{
- //Initialize to avoid warnings
- boost::int32_t nsignals_was_left = 0;
- boost::int32_t nwaiters_was_gone = 0;
-
- m_sem_block_lock.wait();
- ++m_nwaiters_blocked;
- m_sem_block_lock.post();
-
- struct scoped_unlock
- {
- InterprocessMutex & mut;
- scoped_unlock(InterprocessMutex & m)
- : mut(m)
- { m.unlock(); }
-
- ~scoped_unlock()
- { mut.lock(); }
- } unlocker(mtxExternal);
-
-
- bool bTimedOut = tout_enabled ? !m_sem_block_queue.timed_wait(abs_time) : (m_sem_block_queue.wait(), false);
-
- {
- scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
- if ( 0 != (nsignals_was_left = m_nwaiters_to_unblock) ) {
- if ( bTimedOut ) { // timeout (or canceled)
- if ( 0 != m_nwaiters_blocked ) {
- m_nwaiters_blocked--;
- }
- else {
- m_nwaiters_gone++; // count spurious wakeups.
- }
- }
- if ( 0 == --m_nwaiters_to_unblock ) {
- if ( 0 != m_nwaiters_blocked ) {
- m_sem_block_lock.post(); // open the gate.
- nsignals_was_left = 0; // do not open the gate below again.
- }
- else if ( 0 != (nwaiters_was_gone = m_nwaiters_gone) ) {
- m_nwaiters_gone = 0;
- }
- }
- }
- else if ( (std::numeric_limits<boost::int32_t>::max)()/2
- == ++m_nwaiters_gone ) { // timeout/canceled or spurious semaphore :-)
- m_sem_block_lock.wait();
- m_nwaiters_blocked -= m_nwaiters_gone; // something is going on here - test of timeouts? :-)
- m_sem_block_lock.post();
- m_nwaiters_gone = 0;
- }
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- }
-
- if ( 1 == nsignals_was_left ) {
- if ( 0 != nwaiters_was_gone ) {
- // sem_adjust( m_sem_block_queue,-nwaiters_was_gone );
- while ( nwaiters_was_gone-- ) {
- m_sem_block_queue.wait(); // better now than spurious later
- }
- }
- m_sem_block_lock.post(); // open the gate
- }
-
- //mtxExternal.lock(); called from unlocker
-
- return ( bTimedOut ) ? false : true;
-}
+{ return algorithm_type::wait(m_condition_data, true, abs_time, mut); }
} //namespace ipcdetail
} //namespace interprocess
Modified: branches/release/boost/interprocess/sync/windows/mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/windows/mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/windows/mutex.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -19,8 +19,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -51,7 +52,7 @@
: id_()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//Create mutex with the initial count
bool open_or_created;
handles.obtain_mutex(this->id_, &open_or_created);
@@ -64,68 +65,44 @@
inline windows_mutex::~windows_mutex()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_mutex::lock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ mut.lock();
}
inline bool windows_mutex::try_lock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, 0);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.try_lock();
}
inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- boost::posix_time::ptime now
- = boost::posix_time::microsec_clock::universal_time();
-
- unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, ms);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.timed_lock(abs_time);
}
inline void windows_mutex::unlock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- int ret = winapi::release_mutex(hnd);
- (void)ret;
- assert(ret);
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.unlock();
}
} //namespace ipcdetail {
Modified: branches/release/boost/interprocess/sync/windows/semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/windows/semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/windows/semaphore.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -19,8 +19,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -50,7 +51,7 @@
: id_()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//Force smeaphore creation with the initial count
bool open_or_created;
handles.obtain_semaphore(this->id_, initialCount, &open_or_created);
@@ -63,69 +64,43 @@
inline windows_semaphore::~windows_semaphore()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_semaphore::wait(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ sem.wait();
}
inline bool windows_semaphore::try_wait(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, 0);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ return sem.try_wait();
}
inline bool windows_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
- boost::posix_time::ptime now
- = boost::posix_time::microsec_clock::universal_time();
-
- unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, ms);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ return sem.timed_wait(abs_time);
}
inline void windows_semaphore::post(long release_count)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
- //This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- long prev_count;
- int ret = winapi::release_semaphore(hnd, release_count, &prev_count);
- (void)ret;
- assert(ret);
+ windows_intermodule_singleton<sync_handles>::get();
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ sem.post(release_count);
}
} //namespace ipcdetail {
Modified: branches/release/boost/interprocess/sync/windows/sync_utils.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/windows/sync_utils.hpp (original)
+++ branches/release/boost/interprocess/sync/windows/sync_utils.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -21,6 +21,8 @@
#include <boost/interprocess/sync/spin/mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
#include <boost/unordered/unordered_map.hpp>
#include <cstddef>
@@ -32,6 +34,7 @@
{
const std::size_t need_mem = mem_length*2+1;
if(out_length < need_mem){
+ out_length = need_mem;
return false;
}
@@ -51,10 +54,14 @@
struct sync_id
{
+ typedef __int64 internal_type;
+ internal_type rand;
+
sync_id()
{ winapi::query_performance_counter(&rand); }
- __int64 rand;
+ explicit sync_id(internal_type val)
+ { rand = val; }
friend std::size_t hash_value(const sync_id &m)
{ return boost::hash_value(m.rand); }
@@ -62,16 +69,7 @@
friend bool operator==(const sync_id &l, const sync_id &r)
{ return l.rand == r.rand; }
};
-/*
-#define BOOST_NO_LONG_LONG ss
-
-#if defined(BOOST_NO_LONG_LONG)
-#error "defined(BOOST_NO_LONG_LONG)"
-#else
-#error "NOT defined(BOOST_NO_LONG_LONG)"
-#endif
-*/
class sync_handles
{
public:
@@ -108,20 +106,24 @@
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_semaphore
- (name, (long)initial_count, (long)(((unsigned long)(-1))>>1), unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_semaphore_wrapper sem_wrapper;
+ sem_wrapper.open_or_create(name, (long)initial_count, unrestricted_security);
+ erase_and_throw_if_error(sem_wrapper.handle(), id);
+ return sem_wrapper.release();
}
void* open_or_create_mutex(const sync_id &id)
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_mutex
- (name, false, unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_mutex_wrapper mtx_wrapper;
+ mtx_wrapper.open_or_create(name, unrestricted_security);
+ erase_and_throw_if_error(mtx_wrapper.handle(), id);
+ return mtx_wrapper.release();
}
public:
@@ -158,7 +160,6 @@
}
private:
- winapi::interprocess_all_access_security unrestricted_security;
spin_mutex mtx_;
map_type map_;
};
Modified: branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp (original)
+++ branches/release/boost/intrusive/detail/has_member_function_callable_with.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -10,7 +10,7 @@
// sample.h
-#if !BOOST_PP_IS_ITERATING
+#if !defined(BOOST_PP_IS_ITERATING)
#ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
#define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
@@ -113,7 +113,7 @@
};
//!
- #if !defined(_MSC_VER) || (_MSC_VER != 1600)
+ #if !defined(_MSC_VER) || (_MSC_VER < 1600)
#if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
@@ -126,7 +126,7 @@
static const bool value = true;
};
- #else
+ #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
//Special case for 0 args
template< class F
@@ -162,7 +162,7 @@
static const bool value = sizeof(Test< Fun >(0))
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
};
- #endif
+ #endif //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
#else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
template<typename Fun>
Modified: branches/release/boost/intrusive/detail/memory_util.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/memory_util.hpp (original)
+++ branches/release/boost/intrusive/detail/memory_util.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -251,6 +251,13 @@
typedef Ptr<U, Tn...> type;
};
+//Needed for non-conforming compilers like GCC 4.3
+template <template <class> class Ptr, typename T, class U>
+struct type_rebinder<Ptr<T>, U, 0u >
+{
+ typedef Ptr<U> type;
+};
+
#else //C++03 compilers
#define BOOST_PP_LOCAL_MACRO(n) \
Modified: branches/release/boost/move/move.hpp
==============================================================================
--- branches/release/boost/move/move.hpp (original)
+++ branches/release/boost/move/move.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -350,6 +350,15 @@
::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
//
+ #define BOOST_RV_REF_BEG\
+ ::boost::rv< \
+ //
+
+ #define BOOST_RV_REF_END\
+ >& \
+ //
+
+
#define BOOST_FWD_REF(TYPE)\
const TYPE & \
@@ -363,6 +372,14 @@
const ::boost::rv< TYPE >& \
//
+ #define BOOST_COPY_ASSIGN_REF_BEG \
+ const ::boost::rv< \
+ //
+
+ #define BOOST_COPY_ASSIGN_REF_END \
+ >& \
+ //
+
#define BOOST_MOVE_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
const ::boost::rv< TYPE<ARG1, ARG2> >& \
//
@@ -569,6 +586,25 @@
TYPE && \
//
+ //!This macro is used to achieve portable syntax in move
+ //!constructors and assignments for template classes marked as
+ //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
+ //!As macros have problem with comma-separatd template arguments,
+ //!the template argument must be preceded with BOOST_RV_REF_START
+ //!and ended with BOOST_RV_REF_END
+ #define BOOST_RV_REF_BEG\
+ \
+ //
+
+ //!This macro is used to achieve portable syntax in move
+ //!constructors and assignments for template classes marked as
+ //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
+ //!As macros have problem with comma-separatd template arguments,
+ //!the template argument must be preceded with BOOST_RV_REF_START
+ //!and ended with BOOST_RV_REF_END
+ #define BOOST_RV_REF_END\
+ && \
+
//!This macro is used to achieve portable syntax in copy
//!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
#define BOOST_COPY_ASSIGN_REF(TYPE)\
Modified: branches/release/libs/container/doc/Jamfile.v2
==============================================================================
--- branches/release/libs/container/doc/Jamfile.v2 (original)
+++ branches/release/libs/container/doc/Jamfile.v2 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
# Boost.Container library documentation Jamfile ---------------------------------
#
-# Copyright Ion Gaztanaga 2009-2011. Use, modification and
+# Copyright Ion Gaztanaga 2009-2012. Use, modification and
# distribution is 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)
@@ -27,6 +27,8 @@
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_RV_REF(T)=T &&\" \\
+ \"BOOST_RV_REF_BEG=\" \\
+ \"BOOST_RV_REF_END=&&\" \\
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
\"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T<a, b> &&\" \\
\"BOOST_RV_REF_3_TEMPL_ARGS(T,a,b,c)=T<a,b,c>T<a,b,c> &&\" \\
Modified: branches/release/libs/container/doc/container.qbk
==============================================================================
--- branches/release/libs/container/doc/container.qbk (original)
+++ branches/release/libs/container/doc/container.qbk 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,5 +1,5 @@
[/
- / Copyright (c) 2009-2011 Ion Gazta\u00F1aga
+ / Copyright (c) 2009-2012 Ion Gazta\u00F1aga
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,7 +8,7 @@
[library Boost.Container
[quickbook 1.5]
[authors [Gaztanaga, Ion]]
- [copyright 2009-2011 Ion Gaztanaga]
+ [copyright 2009-2012 Ion Gaztanaga]
[id container]
[dirname container]
[purpose Containers library]
@@ -37,9 +37,9 @@
(they can be safely placed in shared memory).
* The library offers new useful containers:
* [classref boost::container::flat_map flat_map],
- [classref boost::container::flat_map flat_set],
- [classref boost::container::flat_map flat_multiset] and
- [classref boost::container::flat_map flat_multiset]: drop-in
+ [classref boost::container::flat_set flat_set],
+ [classref boost::container::flat_multiset flat_multiset] and
+ [classref boost::container::flat_multiset flat_multiset]: drop-in
replacements for standard associative containers but more memory friendly and with faster
searches.
* [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid
@@ -378,7 +378,7 @@
should probably use list instead of slist.]]
[*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement
-insertion and implements it a bit differently for the standard C++11 `forward_list`. `forward_list` has no `size()`
+insertion and implements it a bit differently than the standard C++ `forward_list`. `forward_list` has no `size()`
method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size
with every insertion/erasure, allowing constant-time
`splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers
@@ -422,10 +422,9 @@
by one allocator object could be deallocated by another instance of the same type) and
allocators were not swapped when the container was swapped.
-C++11 further improves stateful allocator support through the
-[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf
-Scoped Allocators model]. [@http://en.cppreference.com/w/cpp/memory/allocator_traits
-`std::allocator_traits`] is the protocol between a container and an allocator, and
+C++11 further improves stateful allocator support through
+[@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`].
+`std::allocator_traits` is the protocol between a container and an allocator, and
an allocator writer can customize its behaviour (should the container propagate it in
move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container]
not only supports this model with C++11 but also [*backports it to C++03].
@@ -437,6 +436,36 @@
[endsect]
+[section:scoped_allocator Scoped allocators]
+
+C++11 improves stateful allocators with the introduction of
+[@http://http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor `std::scoped_allocator_adaptor`]
+class template. `scoped_allocator_adaptor` is instantiated with one outer allocator and zero or more inner
+allocators.
+
+A scoped allocator is a mechanism to automatically propagate the state of the allocator to the subobjects
+of a container in a controlled way. If instantiated with only one allocator type, the inner allocator
+becomes the `scoped_allocator_adaptor` itself, thus using the same allocator
+resource for the container and every element within the container and, if the elements themselves are
+containers, each of their elements recursively. If instantiated with more than one allocator, the first allocator
+is the outer allocator for use by the container, the second allocator is passed to the constructors of the
+container's elements, and, if the elements themselves are containers, the third allocator is passed to the
+elements' elements, and so on.
+
+[*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also
+to C++03 compilers]. Due to C++03 limitations, in those compilers
+the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions
+will be based on traits([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix]
+and [classref boost::container::constructible_with_allocator_prefix constructible_with_allocator_prefix])
+proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf
+N2554: The Scoped Allocator Model (Rev 2) proposal]. In conforming C++11 compilers or compilers supporting SFINAE
+expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules
+(`is_constructible<T, Args..., inner_allocator_type>::value` and
+`is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value`)
+will be used to detect if the allocator must be propagated with suffix or prefix allocator arguments.
+
+[endsect]
+
[section:initializer_lists Initializer lists]
[*Boost.Container] does not support initializer lists when constructing or assigning containers
@@ -585,6 +614,21 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_50_00 Boost 1.50 Release]
+
+* Added Scoped Allocator Model support.
+
+* Fixed bugs
+ [@https://svn.boost.org/trac/boost/ticket/6566 #6566],
+ [@https://svn.boost.org/trac/boost/ticket/6575 #6575],
+ [@https://svn.boost.org/trac/boost/ticket/6606 #6606],
+ [@https://svn.boost.org/trac/boost/ticket/6615 #6615],
+ [@https://svn.boost.org/trac/boost/ticket/6533 #6533],
+ [@https://svn.boost.org/trac/boost/ticket/6536 #6536],
+
+[endsect]
+
+
[section:release_notes_boost_1_49_00 Boost 1.49 Release]
* Fixed bugs
Modified: branches/release/libs/container/example/doc_emplace.cpp
==============================================================================
--- branches/release/libs/container/example/doc_emplace.cpp (original)
+++ branches/release/libs/container/example/doc_emplace.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2009-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)
//
Modified: branches/release/libs/container/example/doc_move_containers.cpp
==============================================================================
--- branches/release/libs/container/example/doc_move_containers.cpp (original)
+++ branches/release/libs/container/example/doc_move_containers.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2009-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)
//
Modified: branches/release/libs/container/example/doc_recursive_containers.cpp
==============================================================================
--- branches/release/libs/container/example/doc_recursive_containers.cpp (original)
+++ branches/release/libs/container/example/doc_recursive_containers.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2009-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)
//
Modified: branches/release/libs/container/example/doc_type_erasure.cpp
==============================================================================
--- branches/release/libs/container/example/doc_type_erasure.cpp (original)
+++ branches/release/libs/container/example/doc_type_erasure.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2009-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)
//
Modified: branches/release/libs/container/index.html
==============================================================================
--- branches/release/libs/container/index.html (original)
+++ branches/release/libs/container/index.html 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,5 +1,5 @@
<!--
-Copyright 2005-2011 Ion Gaztanaga
+Copyright 2005-2012 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)
-->
Modified: branches/release/libs/container/proj/to-do.txt
==============================================================================
--- branches/release/libs/container/proj/to-do.txt (original)
+++ branches/release/libs/container/proj/to-do.txt 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,10 +1,10 @@
->Change "insert" and "push_back"/"push_front" to catch non-const rvalues
->Add an example with stateful allocators
->Add test to check convertible types in push_back/insert
+->Add SCARY iterators.
Review allocator traits
--> Explicit instantiation of simple allocator & std::allocator to detect missing allocator_traits calls
-> Avoid any rebind<>::other
-> Review select_on_container_copy_xxx
-> Review propagate_on_xxx
@@ -12,13 +12,13 @@
-> Default + swap move constructors correct?
-> Review container documentation in swap/copy/move regarding allocators
-Check all move constructors: swap might not be a valid idiom, allocators must be move constructed, intrusive containers are now movable
+Check all move constructors: swap might not be a valid idiom, allocators must be move constructed,
+intrusive containers are now movable
Add and test:
Test different propagation values and with inequal allocators
-
propagate_on_container_move_assignment
select_on_container_copy_construction
propagate_on_container_swap
@@ -28,19 +28,12 @@
An allocator should use a smart allocator not constructible from raw pointers to catch missing pointer_traits calls
-Review all internal container swap's to check allocator propagation is correct
-
Add initializer lists
Write forward_list
-Review all move constructors to test if allocator is move constructed
-
check move if noexcept conditions in vector, deque and stable_vector
-Add new allocator propagation copy constructors
-
-Review all destructors (search for "~") to detect placement destruction and replace it with allocator_traits::destroy
+Detect always equal or unequal allocators at compiler time. operator== returns true_type or false_type
-All functions from base classes like vector_base, node_alloc_holder, etc., should be named with underscore or
-similar to avoid namespace pollution.
\ No newline at end of file
+change virtual functions with pointers to avoid template instantiation for every type
\ No newline at end of file
Modified: branches/release/libs/container/proj/vc7ide/container.sln
==============================================================================
--- branches/release/libs/container/proj/vc7ide/container.sln (original)
+++ branches/release/libs/container/proj/vc7ide/container.sln 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -43,6 +43,14 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_adaptor_test", "scoped_allocator_adaptor.vcproj", "{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_usage_test", "scoped_allocator_usage_test.vcproj", "{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -95,6 +103,14 @@
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.ActiveCfg = Debug|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.ActiveCfg = Debug|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
+ {B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
Modified: branches/release/libs/container/proj/vc7ide/container.vcproj
==============================================================================
--- branches/release/libs/container/proj/vc7ide/container.vcproj (original)
+++ branches/release/libs/container/proj/vc7ide/container.vcproj 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -180,6 +180,9 @@
Name="container"
Filter="">
<File
+ RelativePath="..\..\..\..\boost\container\allocator_traits.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File>
<File
@@ -198,6 +201,9 @@
RelativePath="..\..\..\..\boost\container\map.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\container\scoped_allocator.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\container\set.hpp">
</File>
<File
@@ -216,19 +222,6 @@
RelativePath="..\..\..\..\boost\container\vector.hpp">
</File>
<Filter
- Name="allocator"
- Filter="">
- <File
- RelativePath="..\..\..\..\boost\container\allocator\allocator_traits.hpp">
- </File>
- <File
- RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
- </File>
- <File
- RelativePath="..\..\..\..\boost\container\allocator\scoped_allocator.hpp">
- </File>
- </Filter>
- <Filter
Name="detail"
Filter="">
<File
@@ -265,6 +258,9 @@
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File>
<File
Modified: branches/release/libs/container/test/allocator_traits_test.cpp
==============================================================================
--- branches/release/libs/container/test/allocator_traits_test.cpp (original)
+++ branches/release/libs/container/test/allocator_traits_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2011-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)
//
@@ -9,7 +9,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <cstddef>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/integral_constant.hpp>
Modified: branches/release/libs/container/test/deque_test.cpp
==============================================================================
--- branches/release/libs/container/test/deque_test.cpp (original)
+++ branches/release/libs/container/test/deque_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/dummy_test_allocator.hpp
==============================================================================
--- branches/release/libs/container/test/dummy_test_allocator.hpp (original)
+++ branches/release/libs/container/test/dummy_test_allocator.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -112,10 +112,10 @@
{}
pointer address(reference value)
- { return pointer(addressof(value)); }
+ { return pointer(container_detail::addressof(value)); }
const_pointer address(const_reference value) const
- { return const_pointer(addressof(value)); }
+ { return const_pointer(container_detail::addressof(value)); }
pointer allocate(size_type, cvoid_ptr = 0)
{ return 0; }
Modified: branches/release/libs/container/test/expand_bwd_test_allocator.hpp
==============================================================================
--- branches/release/libs/container/test/expand_bwd_test_allocator.hpp (original)
+++ branches/release/libs/container/test/expand_bwd_test_allocator.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
@@ -86,10 +86,10 @@
, m_offset(other.m_offset), m_allocations(0){ }
pointer address(reference value)
- { return pointer(addressof(value)); }
+ { return pointer(container_detail::addressof(value)); }
const_pointer address(const_reference value) const
- { return const_pointer(addressof(value)); }
+ { return const_pointer(container_detail::addressof(value)); }
pointer allocate(size_type , cvoid_ptr hint = 0)
{ (void)hint; return 0; }
Modified: branches/release/libs/container/test/flat_tree_test.cpp
==============================================================================
--- branches/release/libs/container/test/flat_tree_test.cpp (original)
+++ branches/release/libs/container/test/flat_tree_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
@@ -228,17 +228,17 @@
{
public:
recursive_flat_multiset(const recursive_flat_multiset &c)
- : id_(c.id_), flat_set_(c.flat_set_)
+ : id_(c.id_), flat_multiset_(c.flat_multiset_)
{}
recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
{
id_ = c.id_;
- flat_set_= c.flat_set_;
+ flat_multiset_= c.flat_multiset_;
return *this;
}
int id_;
- flat_multiset<recursive_flat_multiset> flat_set_;
+ flat_multiset<recursive_flat_multiset> flat_multiset_;
friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
{ return a.id_ < b.id_; }
};
Modified: branches/release/libs/container/test/heap_allocator_v1.hpp
==============================================================================
--- branches/release/libs/container/test/heap_allocator_v1.hpp (original)
+++ branches/release/libs/container/test/heap_allocator_v1.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/list_test.cpp
==============================================================================
--- branches/release/libs/container/test/list_test.cpp (original)
+++ branches/release/libs/container/test/list_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/map_test.hpp
==============================================================================
--- branches/release/libs/container/test/map_test.hpp (original)
+++ branches/release/libs/container/test/map_test.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -387,10 +387,17 @@
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
- {
- IntType i1(i);
- IntType i2(i);
- new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
+ { //Check equal_range
+ std::pair<typename MyBoostMultiMap::iterator, typename MyBoostMultiMap::iterator> bret =
+ boostmultimap->equal_range(boostmultimap->begin()->first);
+
+ std::pair<typename MyStdMultiMap::iterator, typename MyStdMultiMap::iterator> sret =
+ stdmultimap->equal_range(stdmultimap->begin()->first);
+
+ if( std::distance(bret.first, bret.second) !=
+ std::distance(sret.first, sret.second) ){
+ return 1;
+ }
}
{
IntType i1(i);
Modified: branches/release/libs/container/test/pair_test.cpp
==============================================================================
--- branches/release/libs/container/test/pair_test.cpp (original)
+++ branches/release/libs/container/test/pair_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2011-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)
//
Modified: branches/release/libs/container/test/print_container.hpp
==============================================================================
--- branches/release/libs/container/test/print_container.hpp (original)
+++ branches/release/libs/container/test/print_container.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/set_test.hpp
==============================================================================
--- branches/release/libs/container/test/set_test.hpp (original)
+++ branches/release/libs/container/test/set_test.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/slist_test.cpp
==============================================================================
--- branches/release/libs/container/test/slist_test.cpp (original)
+++ branches/release/libs/container/test/slist_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/stable_vector_test.cpp
==============================================================================
--- branches/release/libs/container/test/stable_vector_test.cpp (original)
+++ branches/release/libs/container/test/stable_vector_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/string_test.cpp
==============================================================================
--- branches/release/libs/container/test/string_test.cpp (original)
+++ branches/release/libs/container/test/string_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/tree_test.cpp
==============================================================================
--- branches/release/libs/container/test/tree_test.cpp (original)
+++ branches/release/libs/container/test/tree_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
@@ -201,8 +201,10 @@
{
//Now test move semantics
C original;
+ original.emplace();
C move_ctor(boost::move(original));
C move_assign;
+ move_assign.emplace();
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
Modified: branches/release/libs/container/test/util.hpp
==============================================================================
--- branches/release/libs/container/test/util.hpp (original)
+++ branches/release/libs/container/test/util.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/container/test/vector_test.cpp
==============================================================================
--- branches/release/libs/container/test/vector_test.cpp (original)
+++ branches/release/libs/container/test/vector_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
@@ -95,6 +95,26 @@
int main()
{
+ {
+ const std::size_t positions_length = 10;
+ std::size_t positions[positions_length];
+ vector<int> vector_int;
+ vector<int> vector_int2(positions_length);
+ for(std::size_t i = 0; i != positions_length; ++i){
+ positions[i] = 0u;
+ }
+ for(std::size_t i = 0, max = vector_int2.size(); i != max; ++i){
+ vector_int2[i] = i;
+ }
+
+ vector_int.insert(vector_int.begin(), 999);
+
+ vector_int.insert_ordered_at(positions_length, positions + positions_length, vector_int2.end());
+
+ for(std::size_t i = 0, max = vector_int.size(); i != max; ++i){
+ std::cout << vector_int[i] << std::endl;
+ }
+ }
recursive_vector_test();
{
//Now test move semantics
@@ -134,7 +154,8 @@
if(!boost::container::test::test_propagate_allocator<vector>())
return 1;
-
+
return 0;
+
}
#include <boost/container/detail/config_end.hpp>
Modified: branches/release/libs/container/test/vector_test.hpp
==============================================================================
--- branches/release/libs/container/test/vector_test.hpp (original)
+++ branches/release/libs/container/test/vector_test.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// (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)
//
Modified: branches/release/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- branches/release/libs/interprocess/doc/interprocess.qbk (original)
+++ branches/release/libs/interprocess/doc/interprocess.qbk 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -6615,6 +6615,15 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_50_00 Boost 1.50 Release]
+
+* Fixed bugs
+ [@https://svn.boost.org/trac/boost/ticket/3750 #3750],
+ [@https://svn.boost.org/trac/boost/ticket/6727 #6727],
+ [@https://svn.boost.org/trac/boost/ticket/6648 #6648],
+
+[endsect]
+
[section:release_notes_boost_1_49_00 Boost 1.49 Release]
* Fixed bugs
Modified: branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj
==============================================================================
--- branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj (original)
+++ branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -309,6 +309,21 @@
RelativePath="..\..\..\..\boost\interprocess\sync\windows\mutex.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\named_condition.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\named_mutex.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\named_recursive_mutex.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\named_semaphore.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\named_sync.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\sync\windows\recursive_mutex.hpp">
</File>
<File
@@ -317,6 +332,12 @@
<File
RelativePath="..\..\..\..\boost\interprocess\sync\windows\sync_utils.hpp">
</File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\winapi_mutex_wrapper.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\windows\winapi_semaphore_wrapper.hpp">
+ </File>
</Filter>
<Filter
Name="shm"
@@ -340,6 +361,13 @@
RelativePath="..\..\..\..\boost\interprocess\sync\shm\named_upgradable_mutex.hpp">
</File>
</Filter>
+ <Filter
+ Name="detail"
+ Filter="">
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\sync\detail\condition_algorithm_8a.hpp">
+ </File>
+ </Filter>
</Filter>
<Filter
Name="Memory algorithms"
@@ -436,6 +464,9 @@
RelativePath="..\..\..\..\boost\interprocess\detail\config_end.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\file_locking_helpers.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\file_wrapper.hpp">
</File>
<File
@@ -451,6 +482,12 @@
RelativePath="..\..\..\..\boost\interprocess\detail\intersegment_ptr.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\interprocess\detail\lock_file_utilities.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\detail\managed_global_memory.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\interprocess\detail\managed_memory_impl.hpp">
</File>
<File
@@ -528,6 +565,19 @@
<File
RelativePath="..\..\..\..\boost\interprocess\detail\xsi_shared_memory_file_wrapper.hpp">
</File>
+ <Filter
+ Name="intermodule"
+ Filter="">
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\detail\intermodule_singleton_common.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\detail\portable_intermodule_singleton.hpp">
+ </File>
+ <File
+ RelativePath="..\..\..\..\boost\interprocess\detail\windows_intermodule_singleton.hpp">
+ </File>
+ </Filter>
</Filter>
<Filter
Name="Documentation"
Modified: branches/release/libs/interprocess/test/heap_allocator_v1.hpp
==============================================================================
--- branches/release/libs/interprocess/test/heap_allocator_v1.hpp (original)
+++ branches/release/libs/interprocess/test/heap_allocator_v1.hpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -90,7 +90,7 @@
//!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)); }
@@ -98,7 +98,7 @@
//!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) { }
@@ -115,7 +115,11 @@
//!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; return ::new value_type[count]; }
+ {
+ (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)
Modified: branches/release/libs/interprocess/test/named_semaphore_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/named_semaphore_test.cpp (original)
+++ branches/release/libs/interprocess/test/named_semaphore_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -97,6 +97,30 @@
int recursive_named_semaphore_test_wrapper::count_ = 0;
+bool test_named_semaphore_specific()
+{
+ //Test persistance
+ {
+ named_semaphore sem(create_only, SemName, 3);
+ }
+ {
+ named_semaphore sem(open_only, SemName);
+ BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCES_CHECK(sem.try_wait() == false);
+ sem.post();
+ }
+ {
+ named_semaphore sem(open_only, SemName);
+ BOOST_INTERPROCES_CHECK(sem.try_wait() == true);
+ BOOST_INTERPROCES_CHECK(sem.try_wait() == false);
+ }
+
+ named_semaphore::remove(SemName);
+ return true;
+}
+
int main ()
{
try{
@@ -105,6 +129,7 @@
test::test_all_lock<named_semaphore_test_wrapper>();
test::test_all_recursive_lock<recursive_named_semaphore_test_wrapper>();
test::test_all_mutex<false, named_semaphore_test_wrapper>();
+ test_named_semaphore_specific();
}
catch(std::exception &ex){
named_semaphore::remove(SemName);
Modified: branches/release/libs/interprocess/test/vectorstream_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/vectorstream_test.cpp (original)
+++ branches/release/libs/interprocess/test/vectorstream_test.cpp 2012-04-21 16:36:10 EDT (Sat, 21 Apr 2012)
@@ -20,7 +20,8 @@
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <stdio.h>
-using namespace boost::interprocess;
+namespace boost {
+namespace interprocess {
//Force instantiations to catch compile-time errors
typedef basic_string<char> my_string;
@@ -30,6 +31,10 @@
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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk