|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r74160 - in branches/release/boost: container container/detail interprocess interprocess/allocators interprocess/allocators/detail interprocess/containers interprocess/containers/container interprocess/detail interprocess/indexes interprocess/ipc interprocess/mem_algo interprocess/mem_algo/detail interprocess/smart_ptr interprocess/smart_ptr/detail interprocess/sync interprocess/sync/emulation interprocess/sync/posix interprocess/sync/xsi intrusive move
From: igaztanaga_at_[hidden]
Date: 2011-08-30 11:46:30
Author: igaztanaga
Date: 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
New Revision: 74160
URL: http://svn.boost.org/trac/boost/changeset/74160
Log:
Merged for Boost 1.48
Added:
branches/release/boost/container/ (props changed)
branches/release/boost/container/container_fwd.hpp (contents, props changed)
branches/release/boost/container/deque.hpp (contents, props changed)
branches/release/boost/container/detail/ (props changed)
branches/release/boost/container/detail/adaptive_node_pool_impl.hpp (contents, props changed)
branches/release/boost/container/detail/advanced_insert_int.hpp (contents, props changed)
branches/release/boost/container/detail/algorithms.hpp (contents, props changed)
branches/release/boost/container/detail/allocation_type.hpp (contents, props changed)
branches/release/boost/container/detail/config_begin.hpp (contents, props changed)
branches/release/boost/container/detail/config_end.hpp (contents, props changed)
branches/release/boost/container/detail/destroyers.hpp (contents, props changed)
branches/release/boost/container/detail/flat_tree.hpp (contents, props changed)
branches/release/boost/container/detail/iterators.hpp (contents, props changed)
branches/release/boost/container/detail/math_functions.hpp (contents, props changed)
branches/release/boost/container/detail/mpl.hpp (contents, props changed)
branches/release/boost/container/detail/multiallocation_chain.hpp (contents, props changed)
branches/release/boost/container/detail/node_alloc_holder.hpp (contents, props changed)
branches/release/boost/container/detail/node_pool_impl.hpp (contents, props changed)
branches/release/boost/container/detail/pair.hpp (contents, props changed)
branches/release/boost/container/detail/pool_common.hpp (contents, props changed)
branches/release/boost/container/detail/preprocessor.hpp (contents, props changed)
branches/release/boost/container/detail/stored_ref.hpp (contents, props changed)
branches/release/boost/container/detail/transform_iterator.hpp (contents, props changed)
branches/release/boost/container/detail/tree.hpp (contents, props changed)
branches/release/boost/container/detail/type_traits.hpp (contents, props changed)
branches/release/boost/container/detail/utilities.hpp (contents, props changed)
branches/release/boost/container/detail/value_init.hpp (contents, props changed)
branches/release/boost/container/detail/variadic_templates_tools.hpp (contents, props changed)
branches/release/boost/container/detail/version_type.hpp (contents, props changed)
branches/release/boost/container/detail/workaround.hpp (contents, props changed)
branches/release/boost/container/flat_map.hpp (contents, props changed)
branches/release/boost/container/flat_set.hpp (contents, props changed)
branches/release/boost/container/list.hpp (contents, props changed)
branches/release/boost/container/map.hpp (contents, props changed)
branches/release/boost/container/set.hpp (contents, props changed)
branches/release/boost/container/slist.hpp (contents, props changed)
branches/release/boost/container/stable_vector.hpp (contents, props changed)
branches/release/boost/container/string.hpp (contents, props changed)
branches/release/boost/container/vector.hpp (contents, props changed)
branches/release/boost/move/move.hpp
- copied unchanged from r74159, /trunk/boost/move/move.hpp
branches/release/boost/move/move_helpers.hpp
- copied unchanged from r74159, /trunk/boost/move/move_helpers.hpp
Removed:
branches/release/boost/interprocess/containers/container/
Properties modified:
branches/release/boost/interprocess/ (props changed)
branches/release/boost/intrusive/ (props changed)
branches/release/boost/move/ (props changed)
Text files modified:
branches/release/boost/interprocess/allocators/adaptive_pool.hpp | 36 ++++----
branches/release/boost/interprocess/allocators/allocator.hpp | 20 ++--
branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp | 24 +++---
branches/release/boost/interprocess/allocators/cached_node_allocator.hpp | 24 +++---
branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 10 +-
branches/release/boost/interprocess/allocators/detail/allocator_common.hpp | 48 ++++++------
branches/release/boost/interprocess/allocators/detail/node_pool.hpp | 10 +-
branches/release/boost/interprocess/allocators/detail/node_tools.hpp | 4
branches/release/boost/interprocess/allocators/node_allocator.hpp | 36 ++++----
branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp | 24 +++---
branches/release/boost/interprocess/allocators/private_node_allocator.hpp | 24 +++---
branches/release/boost/interprocess/anonymous_shared_memory.hpp | 4
branches/release/boost/interprocess/containers/allocation_type.hpp | 2
branches/release/boost/interprocess/containers/containers_fwd.hpp | 2
branches/release/boost/interprocess/containers/deque.hpp | 2
branches/release/boost/interprocess/containers/flat_map.hpp | 2
branches/release/boost/interprocess/containers/flat_set.hpp | 2
branches/release/boost/interprocess/containers/list.hpp | 2
branches/release/boost/interprocess/containers/map.hpp | 2
branches/release/boost/interprocess/containers/pair.hpp | 2
branches/release/boost/interprocess/containers/set.hpp | 2
branches/release/boost/interprocess/containers/slist.hpp | 2
branches/release/boost/interprocess/containers/stable_vector.hpp | 2
branches/release/boost/interprocess/containers/string.hpp | 2
branches/release/boost/interprocess/containers/vector.hpp | 2
branches/release/boost/interprocess/containers/version_type.hpp | 2
branches/release/boost/interprocess/creation_tags.hpp | 4
branches/release/boost/interprocess/detail/atomic.hpp | 36 ++++----
branches/release/boost/interprocess/detail/cast_tags.hpp | 4
branches/release/boost/interprocess/detail/file_wrapper.hpp | 24 +++---
branches/release/boost/interprocess/detail/in_place_interface.hpp | 4
branches/release/boost/interprocess/detail/intermodule_singleton.hpp | 6
branches/release/boost/interprocess/detail/interprocess_tester.hpp | 4
branches/release/boost/interprocess/detail/intersegment_ptr.hpp | 24 +++---
branches/release/boost/interprocess/detail/managed_memory_impl.hpp | 14 +-
branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp | 6
branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp | 72 +++++++++---------
branches/release/boost/interprocess/detail/math_functions.hpp | 4
branches/release/boost/interprocess/detail/mpl.hpp | 4
branches/release/boost/interprocess/detail/named_proxy.hpp | 34 ++++----
branches/release/boost/interprocess/detail/os_file_functions.hpp | 20 ++++-
branches/release/boost/interprocess/detail/os_thread_functions.hpp | 4
branches/release/boost/interprocess/detail/pointer_type.hpp | 6
branches/release/boost/interprocess/detail/preprocessor.hpp | 2
branches/release/boost/interprocess/detail/robust_emulation.hpp | 10 +-
branches/release/boost/interprocess/detail/segment_manager_helper.hpp | 38 +++++-----
branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp | 4
branches/release/boost/interprocess/detail/transform_iterator.hpp | 2
branches/release/boost/interprocess/detail/type_traits.hpp | 4
branches/release/boost/interprocess/detail/utilities.hpp | 4
branches/release/boost/interprocess/detail/variadic_templates_tools.hpp | 4
branches/release/boost/interprocess/detail/win32_api.hpp | 12 ++
branches/release/boost/interprocess/detail/workaround.hpp | 5 +
branches/release/boost/interprocess/detail/xsi_shared_memory_device.hpp | 36 ++++----
branches/release/boost/interprocess/errors.hpp | 3
branches/release/boost/interprocess/file_mapping.hpp | 20 ++--
branches/release/boost/interprocess/indexes/iunordered_set_index.hpp | 6
branches/release/boost/interprocess/indexes/map_index.hpp | 8 +-
branches/release/boost/interprocess/indexes/unordered_map_index.hpp | 2
branches/release/boost/interprocess/ipc/message_queue.hpp | 44 +++++-----
branches/release/boost/interprocess/managed_external_buffer.hpp | 4
branches/release/boost/interprocess/managed_heap_memory.hpp | 4
branches/release/boost/interprocess/managed_mapped_file.hpp | 24 +++---
branches/release/boost/interprocess/managed_shared_memory.hpp | 24 +++---
branches/release/boost/interprocess/managed_windows_shared_memory.hpp | 22 ++--
branches/release/boost/interprocess/managed_xsi_shared_memory.hpp | 20 ++--
branches/release/boost/interprocess/mapped_region.hpp | 36 ++++----
branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp | 26 +++---
branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp | 4
branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp | 58 +++++++-------
branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 76 ++++++++++----------
branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 20 ++--
branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp | 4
branches/release/boost/interprocess/offset_ptr.hpp | 20 ++--
branches/release/boost/interprocess/permissions.hpp | 6
branches/release/boost/interprocess/segment_manager.hpp | 152 ++++++++++++++++++++--------------------
branches/release/boost/interprocess/shared_memory_object.hpp | 66 ++++++++--------
branches/release/boost/interprocess/smart_ptr/deleter.hpp | 2
branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp | 10 +-
branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp | 14 +-
branches/release/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp | 12 +-
branches/release/boost/interprocess/smart_ptr/enable_shared_from_this.hpp | 4
branches/release/boost/interprocess/smart_ptr/intrusive_ptr.hpp | 10 +-
branches/release/boost/interprocess/smart_ptr/scoped_ptr.hpp | 6
branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp | 40 +++++-----
branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp | 58 +++++++-------
branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp | 10 +-
branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp | 26 +++---
branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp | 16 ++--
branches/release/boost/interprocess/sync/emulation/mutex.hpp | 14 +-
branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp | 14 +-
branches/release/boost/interprocess/sync/emulation/recursive_mutex.hpp | 56 +++++++-------
branches/release/boost/interprocess/sync/file_lock.hpp | 34 ++++----
branches/release/boost/interprocess/sync/interprocess_mutex.hpp | 22 ++++-
branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 21 ++++-
branches/release/boost/interprocess/sync/interprocess_semaphore.hpp | 2
branches/release/boost/interprocess/sync/named_condition.hpp | 26 +++---
branches/release/boost/interprocess/sync/named_mutex.hpp | 30 +++---
branches/release/boost/interprocess/sync/named_recursive_mutex.hpp | 20 ++--
branches/release/boost/interprocess/sync/named_semaphore.hpp | 30 +++---
branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp | 20 ++--
branches/release/boost/interprocess/sync/posix/interprocess_barrier.hpp | 4
branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp | 2
branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp | 19 +++-
branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp | 18 +++-
branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp | 4
branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp | 4
branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 28 +++---
branches/release/boost/interprocess/sync/scoped_lock.hpp | 8 +-
branches/release/boost/interprocess/sync/sharable_lock.hpp | 4
branches/release/boost/interprocess/sync/upgradable_lock.hpp | 4
branches/release/boost/interprocess/sync/xsi/xsi_named_mutex.hpp | 6
branches/release/boost/interprocess/windows_shared_memory.hpp | 18 ++--
branches/release/boost/interprocess/xsi_shared_memory.hpp | 18 ++--
114 files changed, 1021 insertions(+), 945 deletions(-)
Added: branches/release/boost/container/container_fwd.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/container_fwd.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,198 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+#define BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Standard predeclarations
+//////////////////////////////////////////////////////////////////////////////
+
+/// @cond
+
+namespace boost{
+namespace intrusive{
+ //Create namespace to avoid compilation errors
+}}
+
+namespace boost{ namespace container{ namespace containers_detail{
+
+namespace bi = boost::intrusive;
+
+}}}
+
+#ifndef _LIBCPP_VERSION
+
+namespace std {
+
+template <class T>
+class allocator;
+
+template <class T>
+struct less;
+
+template <class T1, class T2>
+struct pair;
+
+template <class CharType>
+struct char_traits;
+
+} //namespace std {
+
+#else
+
+#include <utility>
+#include <memory>
+#include <functional>
+#include <iosfwd>
+
+#endif
+
+/// @endcond
+
+//////////////////////////////////////////////////////////////////////////////
+// Containers
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost {
+namespace container {
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class vector;
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class stable_vector;
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class deque;
+
+//list class
+template <class T
+ ,class A = std::allocator<T> >
+class list;
+
+//slist class
+template <class T
+ ,class A = std::allocator<T> >
+class slist;
+
+//set class
+template <class T
+ ,class Pred = std::less<T>
+ ,class A = std::allocator<T> >
+class set;
+
+//multiset class
+template <class T
+ ,class Pred = std::less<T>
+ ,class A = std::allocator<T> >
+class multiset;
+
+//map class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class A = std::allocator<std::pair<const Key, T> > >
+class map;
+
+//multimap class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class A = std::allocator<std::pair<const Key, T> > >
+class multimap;
+
+//flat_set class
+template <class T
+ ,class Pred = std::less<T>
+ ,class A = std::allocator<T> >
+class flat_set;
+
+//flat_multiset class
+template <class T
+ ,class Pred = std::less<T>
+ ,class A = std::allocator<T> >
+class flat_multiset;
+
+//flat_map class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class A = std::allocator<std::pair<Key, T> > >
+class flat_map;
+
+//flat_multimap class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class A = std::allocator<std::pair<Key, T> > >
+class flat_multimap;
+
+//basic_string class
+template <class CharT
+ ,class Traits = std::char_traits<CharT>
+ ,class A = std::allocator<CharT> >
+class basic_string;
+
+//! Type used to tag that the input range is
+//! guaranteed to be ordered
+struct ordered_range_impl_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
+
+//! Value used to tag that the input range is
+//! guaranteed to be ordered
+static const ordered_range_t ordered_range = 0;
+
+//! 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;
+
+/// @cond
+
+namespace detail_really_deep_namespace {
+
+//Otherwise, gcc issues a warning of previously defined
+//anonymous_instance and unique_instance
+struct dummy
+{
+ dummy()
+ {
+ (void)ordered_range;
+ (void)ordered_unique_range;
+ }
+};
+
+} //detail_really_deep_namespace {
+
+/// @endcond
+
+}} //namespace boost { namespace container {
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
Added: branches/release/boost/container/deque.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/deque.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1881 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1996,1997
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+
+#ifndef BOOST_CONTAINERS_DEQUE_HPP
+#define BOOST_CONTAINERS_DEQUE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/algorithms.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <cstddef>
+#include <iterator>
+#include <boost/assert.hpp>
+#include <memory>
+#include <algorithm>
+#include <stdexcept>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/move/move.hpp>
+#include <boost/move/move_helpers.hpp>
+#include <boost/container/detail/advanced_insert_int.hpp>
+
+namespace boost {
+namespace container {
+
+/// @cond
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class A = std::allocator<T> >
+#else
+template <class T, class A>
+#endif
+class deque;
+
+template <class T, class A>
+struct deque_value_traits
+{
+ typedef T value_type;
+ typedef A allocator_type;
+ static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr_after_move = false;
+ //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_copy = has_trivial_copy<value_type>::value;
+ static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
+ static const bool trivial_assign = has_trivial_assign<value_type>::value;
+ static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
+
+};
+
+// Note: this function is simply a kludge to work around several compilers'
+// bugs in handling constant expressions.
+inline std::size_t deque_buf_size(std::size_t size)
+ { return size < 512 ? std::size_t(512 / size) : std::size_t(1); }
+
+// Deque base class. It has two purposes. First, its constructor
+// and destructor allocate (but don't initialize) storage. This makes
+// exception safety easier.
+template <class T, class A>
+class deque_base
+{
+ public:
+ typedef typename A::value_type val_alloc_val;
+ typedef typename A::pointer val_alloc_ptr;
+ typedef typename A::const_pointer val_alloc_cptr;
+ typedef typename A::reference val_alloc_ref;
+ typedef typename A::const_reference val_alloc_cref;
+ typedef typename A::difference_type val_alloc_diff;
+ typedef typename A::size_type val_alloc_size;
+ typedef typename A::template rebind
+ <typename A::pointer>::other ptr_alloc_t;
+ typedef typename ptr_alloc_t::value_type ptr_alloc_val;
+ typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
+ typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
+ typedef typename ptr_alloc_t::reference ptr_alloc_ref;
+ typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
+ typedef typename A::template
+ rebind<T>::other allocator_type;
+ typedef allocator_type stored_allocator_type;
+ typedef val_alloc_size size_type;
+
+ protected:
+
+ typedef deque_value_traits<T, A> traits_t;
+ typedef typename A::template
+ rebind<typename A::pointer>::other map_allocator_type;
+
+ static size_type s_buffer_size() { return deque_buf_size(sizeof(T)); }
+
+ val_alloc_ptr priv_allocate_node()
+ { return this->alloc().allocate(s_buffer_size()); }
+
+ void priv_deallocate_node(val_alloc_ptr p)
+ { this->alloc().deallocate(p, s_buffer_size()); }
+
+ ptr_alloc_ptr priv_allocate_map(size_type n)
+ { return this->ptr_alloc().allocate(n); }
+
+ void priv_deallocate_map(ptr_alloc_ptr p, size_type n)
+ { this->ptr_alloc().deallocate(p, n); }
+
+ public:
+ // Class invariants:
+ // For any nonsingular iterator i:
+ // i.node is the address of an element in the map array. The
+ // contents of i.node is a pointer to the beginning of a node.
+ // i.first == //(i.node)
+ // i.last == i.first + node_size
+ // i.cur is a pointer in the range [i.first, i.last). NOTE:
+ // the implication of this is that i.cur is always a dereferenceable
+ // pointer, even if i is a past-the-end iterator.
+ // Start and Finish are always nonsingular iterators. NOTE: this means
+ // that an empty deque must have one node, and that a deque
+ // with N elements, where N is the buffer size, must have two nodes.
+ // For every node other than start.node and finish.node, every element
+ // in the node is an initialized object. If start.node == finish.node,
+ // then [start.cur, finish.cur) are initialized objects, and
+ // the elements outside that range are uninitialized storage. Otherwise,
+ // [start.cur, start.last) and [finish.first, finish.cur) are initialized
+ // objects, and [start.first, start.cur) and [finish.cur, finish.last)
+ // are uninitialized storage.
+ // [map, map + map_size) is a valid, non-empty range.
+ // [start.node, finish.node] is a valid range contained within
+ // [map, map + map_size).
+ // A pointer in the range [map, map + map_size) points to an allocated node
+ // if and only if the pointer is in the range [start.node, finish.node].
+ class const_iterator
+ : public std::iterator<std::random_access_iterator_tag,
+ val_alloc_val, val_alloc_diff,
+ val_alloc_cptr, val_alloc_cref>
+ {
+ public:
+ static size_type s_buffer_size() { return deque_base<T, A>::s_buffer_size(); }
+
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef val_alloc_val value_type;
+ typedef val_alloc_cptr pointer;
+ typedef val_alloc_cref reference;
+ typedef val_alloc_diff difference_type;
+
+ typedef ptr_alloc_ptr index_pointer;
+ typedef const_iterator self_t;
+
+ friend class deque<T, A>;
+ friend class deque_base<T, A>;
+
+ protected:
+ val_alloc_ptr m_cur;
+ val_alloc_ptr m_first;
+ val_alloc_ptr m_last;
+ index_pointer m_node;
+
+ public:
+ const_iterator(val_alloc_ptr x, index_pointer y)
+ : m_cur(x), m_first(*y),
+ m_last(*y + s_buffer_size()), m_node(y) {}
+
+ const_iterator() : m_cur(0), m_first(0), m_last(0), m_node(0) {}
+
+ const_iterator(const const_iterator& x)
+ : m_cur(x.m_cur), m_first(x.m_first),
+ m_last(x.m_last), m_node(x.m_node) {}
+
+ reference operator*() const
+ { return *this->m_cur; }
+
+ pointer operator->() const
+ { return this->m_cur; }
+
+ difference_type operator-(const self_t& x) const
+ {
+ if(!this->m_cur && !x.m_cur){
+ return 0;
+ }
+ return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
+ (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
+ }
+
+ self_t& operator++()
+ {
+ ++this->m_cur;
+ if (this->m_cur == this->m_last) {
+ this->priv_set_node(this->m_node + 1);
+ this->m_cur = this->m_first;
+ }
+ return *this;
+ }
+
+ self_t operator++(int)
+ {
+ self_t tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ self_t& operator--()
+ {
+ if (this->m_cur == this->m_first) {
+ this->priv_set_node(this->m_node - 1);
+ this->m_cur = this->m_last;
+ }
+ --this->m_cur;
+ return *this;
+ }
+
+ self_t operator--(int)
+ {
+ self_t tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ self_t& operator+=(difference_type n)
+ {
+ difference_type offset = n + (this->m_cur - this->m_first);
+ if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
+ this->m_cur += n;
+ else {
+ difference_type node_offset =
+ offset > 0 ? offset / difference_type(this->s_buffer_size())
+ : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
+ this->priv_set_node(this->m_node + node_offset);
+ this->m_cur = this->m_first +
+ (offset - node_offset * difference_type(this->s_buffer_size()));
+ }
+ return *this;
+ }
+
+ self_t operator+(difference_type n) const
+ { self_t tmp = *this; return tmp += n; }
+
+ self_t& operator-=(difference_type n)
+ { return *this += -n; }
+
+ self_t operator-(difference_type n) const
+ { self_t tmp = *this; return tmp -= n; }
+
+ reference operator[](difference_type n) const
+ { return *(*this + n); }
+
+ bool operator==(const self_t& x) const
+ { return this->m_cur == x.m_cur; }
+
+ bool operator!=(const self_t& x) const
+ { return !(*this == x); }
+
+ bool operator<(const self_t& x) const
+ {
+ return (this->m_node == x.m_node) ?
+ (this->m_cur < x.m_cur) : (this->m_node < x.m_node);
+ }
+
+ bool operator>(const self_t& x) const
+ { return x < *this; }
+
+ bool operator<=(const self_t& x) const
+ { return !(x < *this); }
+
+ bool operator>=(const self_t& x) const
+ { return !(*this < x); }
+
+ void priv_set_node(index_pointer new_node)
+ {
+ this->m_node = new_node;
+ this->m_first = *new_node;
+ this->m_last = this->m_first + difference_type(this->s_buffer_size());
+ }
+
+ friend const_iterator operator+(difference_type n, const const_iterator& x)
+ { return x + n; }
+ };
+
+ //Deque iterator
+ class iterator : public const_iterator
+ {
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef val_alloc_val value_type;
+ typedef val_alloc_ptr pointer;
+ typedef val_alloc_ref reference;
+ typedef val_alloc_diff difference_type;
+ typedef ptr_alloc_ptr index_pointer;
+ typedef const_iterator self_t;
+
+ friend class deque<T, A>;
+ friend class deque_base<T, A>;
+
+ private:
+ explicit iterator(const const_iterator& x) : const_iterator(x){}
+
+ public:
+ //Constructors
+ iterator(val_alloc_ptr x, index_pointer y) : const_iterator(x, y){}
+ iterator() : const_iterator(){}
+ //iterator(const const_iterator &cit) : const_iterator(cit){}
+ iterator(const iterator& x) : const_iterator(x){}
+
+ //Pointer like operators
+ reference operator*() const { return *this->m_cur; }
+ pointer operator->() const { return this->m_cur; }
+
+ reference operator[](difference_type n) const { return *(*this + n); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->const_iterator::operator++(); return *this; }
+
+ iterator operator++(int)
+ { iterator tmp = *this; ++*this; return tmp; }
+
+ iterator& operator--()
+ { this->const_iterator::operator--(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp = *this; --*this; return tmp; }
+
+ // Arithmetic
+ iterator& operator+=(difference_type off)
+ { this->const_iterator::operator+=(off); return *this; }
+
+ iterator operator+(difference_type off) const
+ { return iterator(this->const_iterator::operator+(off)); }
+
+ friend iterator operator+(difference_type off, const iterator& right)
+ { return iterator(off+static_cast<const const_iterator &>(right)); }
+
+ iterator& operator-=(difference_type off)
+ { this->const_iterator::operator-=(off); return *this; }
+
+ iterator operator-(difference_type off) const
+ { return iterator(this->const_iterator::operator-(off)); }
+
+ difference_type operator-(const const_iterator& right) const
+ { return static_cast<const const_iterator&>(*this) - right; }
+ };
+
+ deque_base(const allocator_type& a, size_type num_elements)
+ : members_(a)
+ { this->priv_initialize_map(num_elements); }
+
+ deque_base(const allocator_type& a)
+ : members_(a)
+ {}
+
+ ~deque_base()
+ {
+ if (this->members_.m_map) {
+ this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ }
+ }
+
+ private:
+ deque_base(const deque_base&);
+
+ protected:
+
+ void priv_initialize_map(size_type num_elements)
+ {
+// if(num_elements){
+ size_type num_nodes = num_elements / s_buffer_size() + 1;
+
+ this->members_.m_map_size = containers_detail::max_value((size_type) InitialMapSize, num_nodes + 2);
+ this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
+
+ ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
+ ptr_alloc_ptr nfinish = nstart + num_nodes;
+
+ BOOST_TRY {
+ this->priv_create_nodes(nstart, nfinish);
+ }
+ BOOST_CATCH(...){
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ this->members_.m_map = 0;
+ this->members_.m_map_size = 0;
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+
+ this->members_.m_start.priv_set_node(nstart);
+ this->members_.m_finish.priv_set_node(nfinish - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
+ num_elements % s_buffer_size();
+// }
+ }
+
+ void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+ {
+ ptr_alloc_ptr cur;
+ BOOST_TRY {
+ for (cur = nstart; cur < nfinish; ++cur)
+ *cur = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_nodes(nstart, cur);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+ {
+ for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
+ this->priv_deallocate_node(*n);
+ }
+
+ void priv_clear_map()
+ {
+ if (this->members_.m_map) {
+ this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ this->members_.m_map = 0;
+ this->members_.m_map_size = 0;
+ this->members_.m_start = iterator();
+ this->members_.m_finish = this->members_.m_start;
+ }
+ }
+
+ enum { InitialMapSize = 8 };
+
+ protected:
+ struct members_holder
+ : public ptr_alloc_t
+ , public allocator_type
+ {
+ members_holder(const allocator_type &a)
+ : map_allocator_type(a), allocator_type(a)
+ , m_map(0), m_map_size(0)
+ , m_start(), m_finish(m_start)
+ {}
+
+ ptr_alloc_ptr m_map;
+ typename allocator_type::size_type m_map_size;
+ iterator m_start;
+ iterator m_finish;
+ } members_;
+
+ ptr_alloc_t &ptr_alloc()
+ { return members_; }
+
+ const ptr_alloc_t &ptr_alloc() const
+ { return members_; }
+
+ allocator_type &alloc()
+ { return members_; }
+
+ const allocator_type &alloc() const
+ { return members_; }
+};
+/// @endcond
+
+//! Deque class
+//!
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class A = std::allocator<T> >
+#else
+template <class T, class A>
+#endif
+class deque : protected deque_base<T, A>
+{
+ /// @cond
+ typedef deque_base<T, A> Base;
+
+ public: // Basic types
+ typedef typename A::value_type val_alloc_val;
+ typedef typename A::pointer val_alloc_ptr;
+ typedef typename A::const_pointer val_alloc_cptr;
+ typedef typename A::reference val_alloc_ref;
+ typedef typename A::const_reference val_alloc_cref;
+ typedef typename A::size_type val_alloc_size;
+ typedef typename A::difference_type val_alloc_diff;
+
+ typedef typename A::template
+ rebind<val_alloc_ptr>::other ptr_alloc_t;
+ typedef typename ptr_alloc_t::value_type ptr_alloc_val;
+ typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
+ typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
+ typedef typename ptr_alloc_t::reference ptr_alloc_ref;
+ typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
+ /// @endcond
+
+ typedef T value_type;
+ typedef val_alloc_ptr pointer;
+ typedef val_alloc_cptr const_pointer;
+ typedef val_alloc_ref reference;
+ typedef val_alloc_cref const_reference;
+ typedef val_alloc_size size_type;
+ typedef val_alloc_diff difference_type;
+ typedef typename Base::allocator_type allocator_type;
+
+ public: // Iterators
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ /// @cond
+
+ private: // Internal typedefs
+ BOOST_COPYABLE_AND_MOVABLE(deque)
+ typedef ptr_alloc_ptr index_pointer;
+ static size_type s_buffer_size()
+ { return Base::s_buffer_size(); }
+ typedef containers_detail::advanced_insert_aux_int<value_type, iterator> advanced_insert_aux_int_t;
+ typedef repeat_iterator<T, difference_type> r_iterator;
+ typedef boost::move_iterator<r_iterator> move_it;
+
+ /// @endcond
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const { return Base::alloc(); }
+
+ public: // Basic accessors
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return this->members_.m_start; }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return this->members_.m_finish; }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->members_.m_start; }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->members_.m_finish; }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->members_.m_finish); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator(this->members_.m_finish); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return const_reverse_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return this->members_.m_start; }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return this->members_.m_finish; }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->members_.m_finish); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->members_.m_start); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n)
+ { return this->members_.m_start[difference_type(n)]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n) const
+ { return this->members_.m_start[difference_type(n)]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n)
+ { this->priv_range_check(n); return (*this)[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n) const
+ { this->priv_range_check(n); return (*this)[n]; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front() { return *this->members_.m_start; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->members_.m_start; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back() { return *(end()-1); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back() const { return *(cend()-1); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->members_.m_finish - this->members_.m_start; }
+
+ //! <b>Effects</b>: Returns the largest possible size of the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return this->alloc().max_size(); }
+
+ //! <b>Effects</b>: Returns true if the deque contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return this->members_.m_finish == this->members_.m_start; }
+
+ //! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit deque(const allocator_type& a = allocator_type())
+ : Base(a)
+ {}
+
+ //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+ //! and inserts n default contructed values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit deque(size_type n) : Base(allocator_type(), n)
+ {
+ containers_detail::default_construct_aux_proxy<T, iterator, size_type> proxy(n);
+ proxy.uninitialized_copy_all_to(this->begin());
+ //deque_base will deallocate in case of exception...
+ }
+
+ //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ deque(size_type n, const value_type& value,
+ const allocator_type& a = allocator_type()) : Base(a, n)
+ { this->priv_fill_initialize(value); }
+
+ //! <b>Effects</b>: Copy constructs a deque.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ deque(const deque& x)
+ : Base(x.alloc())
+ {
+ if(x.size()){
+ this->priv_initialize_map(x.size());
+ std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start);
+ }
+ }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ deque(BOOST_RV_REF(deque) mx)
+ : Base(mx.alloc())
+ { this->swap(mx); }
+
+ //! <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.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InpIt>
+ deque(InpIt first, InpIt last, const allocator_type& a = allocator_type())
+ : Base(a)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_initialize_dispatch(first, last, Result());
+ }
+
+ //! <b>Effects</b>: Destroys the deque. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~deque()
+ {
+ priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+ }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x)
+ {
+ const size_type len = size();
+ if (&x != this) {
+ if (len >= x.size())
+ this->erase(std::copy(x.begin(), x.end(), this->members_.m_start), this->members_.m_finish);
+ else {
+ const_iterator mid = x.begin() + difference_type(len);
+ std::copy(x.begin(), mid, this->members_.m_start);
+ this->insert(this->members_.m_finish, mid, x.end());
+ }
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear.
+ deque& operator= (BOOST_RV_REF(deque) x)
+ {
+ this->clear();
+ this->swap(x);
+ return *this;
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(deque &x)
+ {
+ std::swap(this->members_.m_start, x.members_.m_start);
+ std::swap(this->members_.m_finish, x.members_.m_finish);
+ std::swap(this->members_.m_map, x.members_.m_map);
+ std::swap(this->members_.m_map_size, x.members_.m_map_size);
+ }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InpIt>
+ void assign(InpIt first, InpIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the end of the deque.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(const T &x);
+
+ //! <b>Effects</b>: Constructs a new element in the end of the deque
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+ #endif
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the front of the deque.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(const T &x);
+
+ //! <b>Effects</b>: Constructs a new element in the front of the deque
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+ #endif
+
+ //! <b>Effects</b>: Removes the last element from the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ void pop_back()
+ {
+ if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
+ --this->members_.m_finish.m_cur;
+ containers_detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
+ }
+ else
+ this->priv_pop_back_aux();
+ }
+
+ //! <b>Effects</b>: Removes the first element from the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ void pop_front()
+ {
+ if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
+ containers_detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
+ ++this->members_.m_start.m_cur;
+ }
+ else
+ this->priv_pop_front_aux();
+ }
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before position.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, const T &x);
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before position with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+ #endif
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert n copies of x before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void insert(const_iterator pos, size_type n, const value_type& x)
+ { this->priv_fill_insert(pos, n, x); }
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last).
+ template <class InpIt>
+ void insert(const_iterator pos, InpIt first, InpIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(pos, first, last, Result());
+ }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the deque.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(boost::forward<Args>(args)...);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ typedef containers_detail::advanced_insert_aux_emplace<T, iterator, Args...> type;
+ type &&proxy = type(boost::forward<Args>(args)...);
+ this->priv_insert_aux_impl(this->cend(), 1, proxy);
+ }
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the beginning of the deque.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(boost::forward<Args>(args)...);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ typedef containers_detail::advanced_insert_aux_emplace<T, iterator, Args...> type;
+ type &&proxy = type(boost::forward<Args>(args)...);
+ this->priv_insert_aux_impl(this->cbegin(), 1, proxy);
+ }
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ {
+ if(p == this->cbegin()){
+ this->emplace_front(boost::forward<Args>(args)...);
+ return this->begin();
+ }
+ else if(p == this->cend()){
+ this->emplace_back(boost::forward<Args>(args)...);
+ return (this->end()-1);
+ }
+ else{
+ size_type n = p - this->cbegin();
+ typedef containers_detail::advanced_insert_aux_emplace<T, iterator, Args...> type;
+ type &&proxy = type(boost::forward<Args>(args)...);
+ this->priv_insert_aux_impl(p, 1, proxy);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_back()
+ {
+ if(priv_push_front_simple_available()){
+ new(priv_push_front_simple_pos())value_type();
+ priv_push_front_simple_commit();
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(cend(), 1, proxy);
+ }
+ }
+
+ void emplace_front()
+ {
+ if(priv_push_front_simple_available()){
+ new(priv_push_front_simple_pos())value_type();
+ priv_push_front_simple_commit();
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(cbegin(), 1, proxy);
+ }
+ }
+
+ iterator emplace(const_iterator p)
+ {
+ if(p == cbegin()){
+ emplace_front();
+ return begin();
+ }
+ else if(p == cend()){
+ emplace_back();
+ return (end()-1);
+ }
+ else{
+ size_type n = p - cbegin();
+ containers_detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(p, 1, proxy);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ //advanced_insert_int.hpp includes all necessary preprocessor machinery...
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ if(priv_push_back_simple_available()){ \
+ new(priv_push_back_simple_pos())value_type \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_push_back_simple_commit(); \
+ } \
+ else{ \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_insert_aux_impl(cend(), 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ if(priv_push_front_simple_available()){ \
+ new(priv_push_front_simple_pos())value_type \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_push_front_simple_commit(); \
+ } \
+ else{ \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_insert_aux_impl(cbegin(), 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ if(p == this->cbegin()){ \
+ this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ return this->begin(); \
+ } \
+ else if(p == cend()){ \
+ this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ return (this->end()-1); \
+ } \
+ else{ \
+ size_type pos_num = p - this->cbegin(); \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ this->priv_insert_aux_impl(p, 1, proxy); \
+ return iterator(this->begin() + pos_num); \
+ } \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const value_type& x)
+ {
+ const size_type len = size();
+ if (new_size < len)
+ this->erase(this->members_.m_start + new_size, this->members_.m_finish);
+ else
+ this->insert(this->members_.m_finish, new_size - len, x);
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ const size_type len = size();
+ if (new_size < len)
+ this->erase(this->members_.m_start + new_size, this->members_.m_finish);
+ else{
+ size_type n = new_size - this->size();
+ containers_detail::default_construct_aux_proxy<T, iterator, size_type> proxy(n);
+ priv_insert_aux_impl(this->cend(), n, proxy);
+ }
+ }
+
+ //! <b>Effects</b>: Erases the element at position pos.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the elements between pos and the
+ //! last element (if pos is near the end) or the first element
+ //! if(pos is near the beginning).
+ //! Constant if pos is the first or the last element.
+ iterator erase(const_iterator pos)
+ {
+ const_iterator next = pos;
+ ++next;
+ difference_type index = pos - this->members_.m_start;
+ if (size_type(index) < (this->size() >> 1)) {
+ boost::move_backward(begin(), iterator(pos), iterator(next));
+ pop_front();
+ }
+ else {
+ boost::move(iterator(next), end(), iterator(pos));
+ pop_back();
+ }
+ return this->members_.m_start + index;
+ }
+
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and
+ //! last plus the elements between pos and the
+ //! last element (if pos is near the end) or the first element
+ //! if(pos is near the beginning).
+ iterator erase(const_iterator first, const_iterator last)
+ {
+ if (first == this->members_.m_start && last == this->members_.m_finish) {
+ this->clear();
+ return this->members_.m_finish;
+ }
+ else {
+ difference_type n = last - first;
+ difference_type elems_before = first - this->members_.m_start;
+ if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
+ boost::move_backward(begin(), iterator(first), iterator(last));
+ iterator new_start = this->members_.m_start + n;
+ if(!Base::traits_t::trivial_dctr_after_move)
+ this->priv_destroy_range(this->members_.m_start, new_start);
+ this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
+ this->members_.m_start = new_start;
+ }
+ else {
+ boost::move(iterator(last), end(), iterator(first));
+ iterator new_finish = this->members_.m_finish - n;
+ if(!Base::traits_t::trivial_dctr_after_move)
+ this->priv_destroy_range(new_finish, this->members_.m_finish);
+ this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+ this->members_.m_finish = new_finish;
+ }
+ return this->members_.m_start + elems_before;
+ }
+ }
+
+ //! <b>Effects</b>: Erases all the elements of the deque.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the deque.
+ void clear()
+ {
+ for (index_pointer node = this->members_.m_start.m_node + 1;
+ node < this->members_.m_finish.m_node;
+ ++node) {
+ this->priv_destroy_range(*node, *node + this->s_buffer_size());
+ this->priv_deallocate_node(*node);
+ }
+
+ if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
+ this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
+ this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
+ this->priv_deallocate_node(this->members_.m_finish.m_first);
+ }
+ else
+ this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
+
+ this->members_.m_finish = this->members_.m_start;
+ }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the deque is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void shrink_to_fit()
+ {
+ //This deque implementation already
+ //deallocates excess nodes when erasing
+ //so there is nothing to do except for
+ //empty deque
+ if(this->empty()){
+ this->priv_clear_map();
+ }
+ }
+
+ /// @cond
+ private:
+
+ void priv_range_check(size_type n) const
+ { if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
+
+ iterator priv_insert(const_iterator position, const value_type &x)
+ {
+ if (position == cbegin()){
+ this->push_front(x);
+ return begin();
+ }
+ else if (position == cend()){
+ this->push_back(x);
+ return (end()-1);
+ }
+ else {
+ size_type n = position - cbegin();
+ this->priv_insert_aux(position, size_type(1), x);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ iterator priv_insert(const_iterator position, BOOST_RV_REF(value_type) mx)
+ {
+ if (position == cbegin()) {
+ this->push_front(boost::move(mx));
+ return begin();
+ }
+ else if (position == cend()) {
+ this->push_back(boost::move(mx));
+ return(end()-1);
+ }
+ else {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type n = position - begin();
+ this->priv_insert_aux(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
+ return iterator(this->begin() + n);
+ }
+ }
+
+ void priv_push_front(const value_type &t)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(t);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), size_type(1), t);
+ }
+ }
+
+ void priv_push_front(BOOST_RV_REF(value_type) t)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(boost::move(t));
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ }
+ }
+
+ void priv_push_back(const value_type &t)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(t);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), size_type(1), t);
+ }
+ }
+
+ void priv_push_back(BOOST_RV_REF(T) t)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(boost::move(t));
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ }
+ }
+
+ bool priv_push_back_simple_available() const
+ {
+ return this->members_.m_map &&
+ (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
+ }
+
+ void *priv_push_back_simple_pos() const
+ {
+ return static_cast<void*>(containers_detail::get_pointer(this->members_.m_finish.m_cur));
+ }
+
+ void priv_push_back_simple_commit()
+ {
+ ++this->members_.m_finish.m_cur;
+ }
+
+ bool priv_push_front_simple_available() const
+ {
+ return this->members_.m_map &&
+ (this->members_.m_start.m_cur != this->members_.m_start.m_first);
+ }
+
+ void *priv_push_front_simple_pos() const
+ { return static_cast<void*>(containers_detail::get_pointer(this->members_.m_start.m_cur) - 1); }
+
+ void priv_push_front_simple_commit()
+ { --this->members_.m_start.m_cur; }
+
+ template <class InpIt>
+ void priv_insert_aux(const_iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ for(;first != last; ++first){
+ this->insert(pos, boost::move(value_type(*first)));
+ }
+ }
+
+ template <class FwdIt>
+ void priv_insert_aux(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ { this->priv_insert_aux(pos, first, last); }
+
+ // assign(), a generalized assignment member function. Two
+ // versions: one that takes a count, and one that takes a range.
+ // The range version is a member template, so we dispatch on whether
+ // or not the type is an integer.
+ void priv_fill_assign(size_type n, const T& val)
+ {
+ if (n > size()) {
+ std::fill(begin(), end(), val);
+ this->insert(cend(), n - size(), val);
+ }
+ else {
+ this->erase(cbegin() + n, cend());
+ std::fill(begin(), end(), val);
+ }
+ }
+
+ template <class Integer>
+ void priv_initialize_dispatch(Integer n, Integer x, containers_detail::true_)
+ {
+ this->priv_initialize_map(n);
+ this->priv_fill_initialize(x);
+ }
+
+ template <class InpIt>
+ void priv_initialize_dispatch(InpIt first, InpIt last, containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
+ this->priv_range_initialize(first, last, ItCat());
+ }
+
+ void priv_destroy_range(iterator p, iterator p2)
+ {
+ for(;p != p2; ++p)
+ containers_detail::get_pointer(&*p)->~value_type();
+ }
+
+ void priv_destroy_range(pointer p, pointer p2)
+ {
+ for(;p != p2; ++p)
+ containers_detail::get_pointer(&*p)->~value_type();
+ }
+
+ template <class Integer>
+ void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
+ { this->priv_fill_assign((size_type) n, (value_type)val); }
+
+ template <class InpIt>
+ void priv_assign_dispatch(InpIt first, InpIt last, containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
+ this->priv_assign_aux(first, last, ItCat());
+ }
+
+ template <class InpIt>
+ void priv_assign_aux(InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ iterator cur = begin();
+ for ( ; first != last && cur != end(); ++cur, ++first)
+ *cur = *first;
+ if (first == last)
+ this->erase(cur, cend());
+ else
+ this->insert(cend(), first, last);
+ }
+
+ template <class FwdIt>
+ void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = std::distance(first, last);
+ if (len > size()) {
+ FwdIt mid = first;
+ std::advance(mid, size());
+ std::copy(first, mid, begin());
+ this->insert(cend(), mid, last);
+ }
+ else
+ this->erase(std::copy(first, last, begin()), cend());
+ }
+
+ template <class Integer>
+ void priv_insert_dispatch(const_iterator pos, Integer n, Integer x, containers_detail::true_)
+ { this->priv_fill_insert(pos, (size_type) n, (value_type)x); }
+
+ template <class InpIt>
+ void priv_insert_dispatch(const_iterator pos,InpIt first, InpIt last, containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
+ this->priv_insert_aux(pos, first, last, ItCat());
+ }
+
+ void priv_insert_aux(const_iterator pos, size_type n, const value_type& x)
+ {
+ typedef constant_iterator<value_type, difference_type> c_it;
+ this->priv_insert_aux(pos, c_it(x, n), c_it());
+ }
+
+ //Just forward all operations to priv_insert_aux_impl
+ template <class FwdIt>
+ void priv_insert_aux(const_iterator p, FwdIt first, FwdIt last)
+ {
+ containers_detail::advanced_insert_aux_proxy<T, FwdIt, iterator> proxy(first, last);
+ priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
+ }
+
+ void priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
+ {
+ iterator pos(p);
+ if(!this->members_.m_map){
+ this->priv_initialize_map(0);
+ pos = this->begin();
+ }
+
+ const difference_type elemsbefore = pos - this->members_.m_start;
+ size_type length = this->size();
+ if (elemsbefore < static_cast<difference_type>(length / 2)) {
+ iterator new_start = this->priv_reserve_elements_at_front(n);
+ iterator old_start = this->members_.m_start;
+ pos = this->members_.m_start + elemsbefore;
+ if (elemsbefore >= difference_type(n)) {
+ iterator start_n = this->members_.m_start + difference_type(n);
+ ::boost::uninitialized_move(this->members_.m_start, start_n, new_start);
+ this->members_.m_start = new_start;
+ boost::move(start_n, pos, old_start);
+ interf.copy_all_to(pos - difference_type(n));
+ }
+ else {
+ difference_type mid_count = (difference_type(n) - elemsbefore);
+ iterator mid_start = old_start - mid_count;
+ interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
+ this->members_.m_start = mid_start;
+ ::boost::uninitialized_move(old_start, pos, new_start);
+ this->members_.m_start = new_start;
+ interf.copy_all_to(old_start);
+ }
+ }
+ else {
+ iterator new_finish = this->priv_reserve_elements_at_back(n);
+ iterator old_finish = this->members_.m_finish;
+ const difference_type elemsafter =
+ difference_type(length) - elemsbefore;
+ pos = this->members_.m_finish - elemsafter;
+ if (elemsafter >= difference_type(n)) {
+ iterator finish_n = this->members_.m_finish - difference_type(n);
+ ::boost::uninitialized_move(finish_n, this->members_.m_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ boost::move_backward(pos, finish_n, old_finish);
+ interf.copy_all_to(pos);
+ }
+ else {
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_finish += n-elemsafter;
+ ::boost::uninitialized_move(pos, old_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ interf.copy_all_to(pos);
+ }
+ }
+ }
+
+ void priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
+ {
+ typedef constant_iterator<value_type, difference_type> c_it;
+ this->insert(pos, c_it(x, n), c_it());
+ }
+
+ // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
+ // but none of the deque's elements have yet been constructed.
+ void priv_fill_initialize(const value_type& value)
+ {
+ index_pointer cur;
+ BOOST_TRY {
+ for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
+ std::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
+ }
+ std::uninitialized_fill(this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template <class InpIt>
+ void priv_range_initialize(InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ this->priv_initialize_map(0);
+ BOOST_TRY {
+ for ( ; first != last; ++first)
+ this->push_back(*first);
+ }
+ BOOST_CATCH(...){
+ this->clear();
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template <class FwdIt>
+ void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type n = 0;
+ n = std::distance(first, last);
+ this->priv_initialize_map(n);
+
+ index_pointer cur_node;
+ BOOST_TRY {
+ for (cur_node = this->members_.m_start.m_node;
+ cur_node < this->members_.m_finish.m_node;
+ ++cur_node) {
+ FwdIt mid = first;
+ std::advance(mid, this->s_buffer_size());
+ ::boost::uninitialized_copy_or_move(first, mid, *cur_node);
+ first = mid;
+ }
+ ::boost::uninitialized_copy_or_move(first, last, this->members_.m_finish.m_first);
+ }
+ BOOST_CATCH(...){
+ this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
+ void priv_pop_back_aux()
+ {
+ this->priv_deallocate_node(this->members_.m_finish.m_first);
+ this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
+ containers_detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
+ }
+
+ // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
+ // if the deque has at least one element (a precondition for this member
+ // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
+ // must have at least two nodes.
+ void priv_pop_front_aux()
+ {
+ containers_detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
+ this->priv_deallocate_node(this->members_.m_start.m_first);
+ this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
+ }
+
+ iterator priv_reserve_elements_at_front(size_type n)
+ {
+ size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
+ if (n > vacancies){
+ size_type new_elems = n-vacancies;
+ size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
+ this->s_buffer_size();
+ size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
+ if (new_nodes > s){
+ this->priv_reallocate_map(new_nodes, true);
+ }
+ size_type i = 1;
+ BOOST_TRY {
+ for (; i <= new_nodes; ++i)
+ *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...) {
+ for (size_type j = 1; j < i; ++j)
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ return this->members_.m_start - difference_type(n);
+ }
+
+ iterator priv_reserve_elements_at_back(size_type n)
+ {
+ size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
+ if (n > vacancies){
+ size_type new_elems = n - vacancies;
+ size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
+ size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
+ if (new_nodes + 1 > s){
+ this->priv_reallocate_map(new_nodes, false);
+ }
+ size_type i;
+ BOOST_TRY {
+ for (i = 1; i <= new_nodes; ++i)
+ *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...) {
+ for (size_type j = 1; j < i; ++j)
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ return this->members_.m_finish + difference_type(n);
+ }
+
+ void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
+ {
+ size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
+ size_type new_num_nodes = old_num_nodes + nodes_to_add;
+
+ index_pointer new_nstart;
+ if (this->members_.m_map_size > 2 * new_num_nodes) {
+ new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+ + (add_at_front ? nodes_to_add : 0);
+ if (new_nstart < this->members_.m_start.m_node)
+ boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ else
+ boost::move_backward
+ (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
+ }
+ else {
+ size_type new_map_size =
+ this->members_.m_map_size + containers_detail::max_value(this->members_.m_map_size, nodes_to_add) + 2;
+
+ index_pointer new_map = this->priv_allocate_map(new_map_size);
+ new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ + (add_at_front ? nodes_to_add : 0);
+ boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+
+ this->members_.m_map = new_map;
+ this->members_.m_map_size = new_map_size;
+ }
+
+ this->members_.m_start.priv_set_node(new_nstart);
+ this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
+ }
+ /// @endcond
+};
+
+// Nonmember functions.
+template <class T, class A>
+inline bool operator==(const deque<T, A>& x,
+ const deque<T, A>& y)
+{
+ return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class A>
+inline bool operator<(const deque<T, A>& x,
+ const deque<T, A>& y)
+{
+ return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T, class A>
+inline bool operator!=(const deque<T, A>& x,
+ const deque<T, A>& y)
+ { return !(x == y); }
+
+template <class T, class A>
+inline bool operator>(const deque<T, A>& x,
+ const deque<T, A>& y)
+ { return y < x; }
+
+template <class T, class A>
+inline bool operator<=(const deque<T, A>& x,
+ const deque<T, A>& y)
+ { return !(y < x); }
+
+template <class T, class A>
+inline bool operator>=(const deque<T, A>& x,
+ const deque<T, A>& y)
+ { return !(x < y); }
+
+
+template <class T, class A>
+inline void swap(deque<T, A>& x, deque<T, A>& y)
+{ x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::container::deque<T, A> >
+{
+ enum { value = has_trivial_destructor<A>::value };
+};
+*/
+}
+
+/// @endcond
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_CONTAINERS_DEQUE_HPP
Added: branches/release/boost/container/detail/adaptive_node_pool_impl.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/adaptive_node_pool_impl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,648 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/math_functions.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/pool_common.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class size_type>
+struct hdr_offset_holder_t
+{
+ hdr_offset_holder_t(size_type offset = 0)
+ : hdr_offset(offset)
+ {}
+ size_type hdr_offset;
+};
+
+template<class VoidPointer, class SizeType>
+struct adaptive_pool_types
+{
+ typedef VoidPointer void_pointer;
+ typedef typename bi::make_set_base_hook
+ < bi::void_pointer<void_pointer>
+ , bi::optimize_size<true>
+ , bi::constant_time_size<false>
+ , bi::link_mode<bi::normal_link> >::type multiset_hook_t;
+
+ typedef hdr_offset_holder_t<SizeType> hdr_offset_holder;
+
+ struct block_info_t
+ :
+ public hdr_offset_holder,
+ public multiset_hook_t
+ {
+ typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
+ //An intrusive list of free node from this block
+ free_nodes_t free_nodes;
+ friend bool operator <(const block_info_t &l, const block_info_t &r)
+ {
+// { return l.free_nodes.size() < r.free_nodes.size(); }
+ //Let's order blocks first by free nodes and then by address
+ //so that highest address fully free blocks are deallocated.
+ //This improves returning memory to the OS (trimming).
+ const bool is_less = l.free_nodes.size() < r.free_nodes.size();
+ const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
+ return is_less || (is_equal && (&l < &r));
+ }
+
+ friend bool operator ==(const block_info_t &l, const block_info_t &r)
+ { return &l == &r; }
+ };
+ typedef typename bi::make_multiset
+ <block_info_t, bi::base_hook<multiset_hook_t> >::type block_multiset_t;
+};
+
+template<class size_type>
+inline size_type calculate_alignment
+ ( size_type overhead_percent, size_type real_node_size
+ , size_type hdr_size, size_type hdr_offset_size, size_type payload_per_allocation)
+{
+ //to-do: handle real_node_size != node_size
+ const size_type divisor = overhead_percent*real_node_size;
+ const size_type dividend = hdr_offset_size*100;
+ size_type elements_per_subblock = (dividend - 1)/divisor + 1;
+ size_type candidate_power_of_2 =
+ upper_power_of_2(elements_per_subblock*real_node_size + hdr_offset_size);
+ bool overhead_satisfied = false;
+ //Now calculate the wors-case overhead for a subblock
+ const size_type max_subblock_overhead = hdr_size + payload_per_allocation;
+ while(!overhead_satisfied){
+ elements_per_subblock = (candidate_power_of_2 - max_subblock_overhead)/real_node_size;
+ const size_type overhead_size = candidate_power_of_2 - elements_per_subblock*real_node_size;
+ if(overhead_size*100/candidate_power_of_2 < overhead_percent){
+ overhead_satisfied = true;
+ }
+ else{
+ candidate_power_of_2 <<= 1;
+ }
+ }
+ return candidate_power_of_2;
+}
+
+template<class size_type>
+inline void calculate_num_subblocks
+ (size_type alignment, size_type real_node_size, size_type elements_per_block
+ , size_type &num_subblocks, size_type &real_num_node, size_type overhead_percent
+ , size_type hdr_size, size_type hdr_offset_size, size_type payload_per_allocation)
+{
+ size_type elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
+ size_type possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
+ size_type hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
+ while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
+ ++possible_num_subblock;
+ }
+ elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
+ bool overhead_satisfied = false;
+ while(!overhead_satisfied){
+ const size_type total_data = (elements_per_subblock*(possible_num_subblock-1) + hdr_subblock_elements)*real_node_size;
+ const size_type total_size = alignment*possible_num_subblock;
+ if((total_size - total_data)*100/total_size < overhead_percent){
+ overhead_satisfied = true;
+ }
+ else{
+ ++possible_num_subblock;
+ }
+ }
+ num_subblocks = possible_num_subblock;
+ real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
+}
+
+template<class SegmentManagerBase, bool AlignOnly = false>
+class private_adaptive_node_pool_impl
+{
+ //Non-copyable
+ private_adaptive_node_pool_impl();
+ private_adaptive_node_pool_impl(const private_adaptive_node_pool_impl &);
+ private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
+ typedef private_adaptive_node_pool_impl this_type;
+
+ typedef typename SegmentManagerBase::void_pointer void_pointer;
+ static const typename SegmentManagerBase::
+ size_type PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
+ typedef bool_<AlignOnly> IsAlignOnly;
+ typedef true_ AlignOnlyTrue;
+ typedef false_ AlignOnlyFalse;
+
+ public:
+ typedef typename node_slist<void_pointer>::node_t node_t;
+ typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
+ typedef typename SegmentManagerBase::size_type size_type;
+
+ private:
+ typedef typename adaptive_pool_types<void_pointer, size_type>::block_info_t block_info_t;
+ typedef typename adaptive_pool_types<void_pointer, size_type>::block_multiset_t block_multiset_t;
+ typedef typename block_multiset_t::iterator block_iterator;
+ typedef typename adaptive_pool_types<void_pointer, size_type>::hdr_offset_holder hdr_offset_holder;
+
+ static const size_type MaxAlign = alignment_of<node_t>::value;
+ static const size_type HdrSize = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
+ static const size_type HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
+
+
+ public:
+ //!Segment manager typedef
+ typedef SegmentManagerBase segment_manager_base_type;
+
+ //!Constructor from a segment manager. Never throws
+ private_adaptive_node_pool_impl
+ ( segment_manager_base_type *segment_mngr_base
+ , size_type node_size
+ , size_type nodes_per_block
+ , size_type max_free_blocks
+ , unsigned char overhead_percent
+ )
+ : m_max_free_blocks(max_free_blocks)
+ , m_real_node_size(lcm(node_size, size_type(alignment_of<node_t>::value)))
+ //Round the size to a power of two value.
+ //This is the total memory size (including payload) that we want to
+ //allocate from the general-purpose allocator
+ , m_real_block_alignment
+ (AlignOnly ?
+ upper_power_of_2(HdrSize + m_real_node_size*nodes_per_block) :
+ calculate_alignment( (size_type)overhead_percent, m_real_node_size
+ , HdrSize, HdrOffsetSize, PayloadPerAllocation))
+ //This is the real number of nodes per block
+ , m_num_subblocks(0)
+ , m_real_num_node(AlignOnly ? (m_real_block_alignment - PayloadPerAllocation - HdrSize)/m_real_node_size : 0)
+ //General purpose allocator
+ , mp_segment_mngr_base(segment_mngr_base)
+ , m_block_multiset()
+ , m_totally_free_blocks(0)
+ {
+ if(!AlignOnly){
+ calculate_num_subblocks
+ ( m_real_block_alignment
+ , m_real_node_size
+ , nodes_per_block
+ , m_num_subblocks
+ , m_real_num_node
+ , (size_type)overhead_percent
+ , HdrSize
+ , HdrOffsetSize
+ , PayloadPerAllocation);
+ }
+ }
+
+ //!Destructor. Deallocates all allocated blocks. Never throws
+ ~private_adaptive_node_pool_impl()
+ { priv_clear(); }
+
+ size_type get_real_num_node() const
+ { return m_real_num_node; }
+
+ //!Returns the segment manager. Never throws
+ segment_manager_base_type* get_segment_manager_base()const
+ { return containers_detail::get_pointer(mp_segment_mngr_base); }
+
+ //!Allocates array of count elements. Can throw
+ void *allocate_node()
+ {
+ priv_invariants();
+ //If there are no free nodes we allocate a new block
+ if (m_block_multiset.empty()){
+ priv_alloc_block(1);
+ }
+ //We take the first free node the multiset can't be empty
+ return priv_take_first_node();
+ }
+
+ //!Deallocates an array pointed by ptr. Never throws
+ void deallocate_node(void *pElem)
+ {
+ multiallocation_chain chain;
+ chain.push_front(void_pointer(pElem));
+ this->priv_reinsert_nodes_in_block(chain, 1);
+ //Update free block count<
+ if(m_totally_free_blocks > m_max_free_blocks){
+ this->priv_deallocate_free_blocks(m_max_free_blocks);
+ }
+ priv_invariants();
+ }
+
+ //!Allocates n nodes.
+ //!Can throw
+ multiallocation_chain allocate_nodes(const size_type n)
+ {
+ multiallocation_chain chain;
+ size_type i = 0;
+ try{
+ priv_invariants();
+ while(i != n){
+ //If there are no free nodes we allocate all needed blocks
+ if (m_block_multiset.empty()){
+ priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
+ }
+ free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+ const size_type free_nodes_count_before = free_nodes.size();
+ if(free_nodes_count_before == m_real_num_node){
+ --m_totally_free_blocks;
+ }
+ const size_type num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
+ for(size_type j = 0; j != num_elems; ++j){
+ void *new_node = &free_nodes.front();
+ free_nodes.pop_front();
+ chain.push_back(new_node);
+ }
+
+ if(free_nodes.empty()){
+ m_block_multiset.erase(m_block_multiset.begin());
+ }
+ i += num_elems;
+ }
+ }
+ catch(...){
+ this->deallocate_nodes(boost::move(chain));
+ throw;
+ }
+ priv_invariants();
+ return boost::move(chain);
+ }
+
+ //!Deallocates a linked list of nodes. Never throws
+ void deallocate_nodes(multiallocation_chain nodes)
+ {
+ this->priv_reinsert_nodes_in_block(nodes, nodes.size());
+ if(m_totally_free_blocks > m_max_free_blocks){
+ this->priv_deallocate_free_blocks(m_max_free_blocks);
+ }
+ }
+
+ void deallocate_free_blocks()
+ { this->priv_deallocate_free_blocks(0); }
+
+ size_type num_free_nodes()
+ {
+ typedef typename block_multiset_t::const_iterator citerator;
+ size_type count = 0;
+ citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
+ for(; it != itend; ++it){
+ count += it->free_nodes.size();
+ }
+ return count;
+ }
+
+ void swap(private_adaptive_node_pool_impl &other)
+ {
+ BOOST_ASSERT(m_max_free_blocks == other.m_max_free_blocks);
+ BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
+ BOOST_ASSERT(m_real_block_alignment == other.m_real_block_alignment);
+ BOOST_ASSERT(m_real_num_node == other.m_real_num_node);
+ std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+ std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
+ m_block_multiset.swap(other.m_block_multiset);
+ }
+
+ //Deprecated, use deallocate_free_blocks
+ void deallocate_free_chunks()
+ { this->priv_deallocate_free_blocks(0); }
+
+ private:
+ void priv_deallocate_free_blocks(size_type max_free_blocks)
+ {
+ priv_invariants();
+ //Now check if we've reached the free nodes limit
+ //and check if we have free blocks. If so, deallocate as much
+ //as we can to stay below the limit
+ for( block_iterator itend = m_block_multiset.end()
+ ; m_totally_free_blocks > max_free_blocks
+ ; --m_totally_free_blocks
+ ){
+ BOOST_ASSERT(!m_block_multiset.empty());
+ block_iterator it = itend;
+ --it;
+ BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
+ m_block_multiset.erase_and_dispose(it, block_destroyer(this));
+ }
+ }
+
+ void priv_reinsert_nodes_in_block(multiallocation_chain &chain, size_type n)
+ {
+ block_iterator block_it(m_block_multiset.end());
+ while(n--){
+ void *pElem = containers_detail::get_pointer(chain.front());
+ chain.pop_front();
+ priv_invariants();
+ block_info_t *block_info = this->priv_block_from_node(pElem);
+ BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
+ //We put the node at the beginning of the free node list
+ node_t * to_deallocate = static_cast<node_t*>(pElem);
+ block_info->free_nodes.push_front(*to_deallocate);
+
+ block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
+ block_iterator next_block(this_block);
+ ++next_block;
+
+ //Cache the free nodes from the block
+ size_type this_block_free_nodes = this_block->free_nodes.size();
+
+ if(this_block_free_nodes == 1){
+ m_block_multiset.insert(m_block_multiset.begin(), *block_info);
+ }
+ else{
+ block_iterator next_block(this_block);
+ ++next_block;
+ if(next_block != block_it){
+ size_type next_free_nodes = next_block->free_nodes.size();
+ if(this_block_free_nodes > next_free_nodes){
+ //Now move the block to the new position
+ m_block_multiset.erase(this_block);
+ m_block_multiset.insert(*block_info);
+ }
+ }
+ }
+ //Update free block count
+ if(this_block_free_nodes == m_real_num_node){
+ ++m_totally_free_blocks;
+ }
+ priv_invariants();
+ }
+ }
+
+ node_t *priv_take_first_node()
+ {
+ BOOST_ASSERT(m_block_multiset.begin() != m_block_multiset.end());
+ //We take the first free node the multiset can't be empty
+ free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+ node_t *first_node = &free_nodes.front();
+ const size_type free_nodes_count = free_nodes.size();
+ BOOST_ASSERT(0 != free_nodes_count);
+ free_nodes.pop_front();
+ if(free_nodes_count == 1){
+ m_block_multiset.erase(m_block_multiset.begin());
+ }
+ else if(free_nodes_count == m_real_num_node){
+ --m_totally_free_blocks;
+ }
+ priv_invariants();
+ return first_node;
+ }
+
+ class block_destroyer;
+ friend class block_destroyer;
+
+ class block_destroyer
+ {
+ public:
+ block_destroyer(const this_type *impl)
+ : mp_impl(impl)
+ {}
+
+ void operator()(typename block_multiset_t::pointer to_deallocate)
+ { return this->do_destroy(to_deallocate, IsAlignOnly()); }
+
+ private:
+ void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyTrue)
+ {
+ size_type free_nodes = to_deallocate->free_nodes.size();
+ (void)free_nodes;
+ BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
+ mp_impl->mp_segment_mngr_base->deallocate(to_deallocate);
+ }
+
+ void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyFalse)
+ {
+ size_type free_nodes = to_deallocate->free_nodes.size();
+ (void)free_nodes;
+ BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
+ BOOST_ASSERT(0 == to_deallocate->hdr_offset);
+ hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(containers_detail::get_pointer(to_deallocate));
+ mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
+ }
+
+ const this_type *mp_impl;
+ };
+
+ //This macro will activate invariant checking. Slow, but helpful for debugging the code.
+ //#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ void priv_invariants()
+ #ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ #undef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ {
+ //We iterate through the block tree to free the memory
+ block_iterator it(m_block_multiset.begin()),
+ itend(m_block_multiset.end()), to_deallocate;
+ if(it != itend){
+ for(++it; it != itend; ++it){
+ block_iterator prev(it);
+ --prev;
+ size_type sp = prev->free_nodes.size(),
+ si = it->free_nodes.size();
+ BOOST_ASSERT(sp <= si);
+ (void)sp; (void)si;
+ }
+ }
+ //Check that the total free nodes are correct
+ it = m_block_multiset.begin();
+ itend = m_block_multiset.end();
+ size_type total_free_nodes = 0;
+ for(; it != itend; ++it){
+ total_free_nodes += it->free_nodes.size();
+ }
+ BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+
+ //Check that the total totally free blocks are correct
+ it = m_block_multiset.begin();
+ itend = m_block_multiset.end();
+ total_free = 0;
+ for(; it != itend; ++it){
+ total_free += it->free_nodes.size() == m_real_num_node;
+ }
+ BOOST_ASSERT(total_free >= m_totally_free_blocks);
+
+ if(!AlignOnly){
+ //Check that header offsets are correct
+ it = m_block_multiset.begin();
+ for(; it != itend; ++it){
+ hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
+ for(size_type i = 0, max = m_num_subblocks; i < max; ++i){
+ BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
+ BOOST_ASSERT(0 == ((size_type)hdr_off_holder & (m_real_block_alignment - 1)));
+ BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+ hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
+ }
+ }
+ }
+ }
+ #else
+ {} //empty
+ #endif
+
+ //!Deallocates all used memory. Never throws
+ void priv_clear()
+ {
+ #ifndef NDEBUG
+ block_iterator it = m_block_multiset.begin();
+ block_iterator itend = m_block_multiset.end();
+ size_type num_free_nodes = 0;
+ for(; it != itend; ++it){
+ //Check for memory leak
+ BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
+ ++num_free_nodes;
+ }
+ BOOST_ASSERT(num_free_nodes == m_totally_free_blocks);
+ #endif
+ //Check for memory leaks
+ priv_invariants();
+ m_block_multiset.clear_and_dispose(block_destroyer(this));
+ m_totally_free_blocks = 0;
+ }
+
+ block_info_t *priv_block_from_node(void *node, AlignOnlyFalse) const
+ {
+ hdr_offset_holder *hdr_off_holder =
+ reinterpret_cast<hdr_offset_holder*>((std::size_t)node & size_type(~(m_real_block_alignment - 1)));
+ BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+ block_info_t *block = reinterpret_cast<block_info_t *>
+ (reinterpret_cast<char*>(hdr_off_holder) + hdr_off_holder->hdr_offset);
+ BOOST_ASSERT(block->hdr_offset == 0);
+ return block;
+ }
+
+ block_info_t *priv_block_from_node(void *node, AlignOnlyTrue) const
+ {
+ return (block_info_t *)((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
+ }
+
+ block_info_t *priv_block_from_node(void *node) const
+ { return priv_block_from_node(node, IsAlignOnly()); }
+
+ hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
+ {
+ hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
+ (reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
+ BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
+ BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+ return hdr_off_holder;
+ }
+
+ //!Allocates a several blocks of nodes. Can throw
+ void priv_alloc_block(size_type n, AlignOnlyTrue)
+ {
+ size_type real_block_size = m_real_block_alignment - PayloadPerAllocation;
+ for(size_type i = 0; i != n; ++i){
+ //We allocate a new NodeBlock and put it the last
+ //element of the tree
+ char *mem_address = static_cast<char*>
+ (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
+ if(!mem_address) throw std::bad_alloc();
+ ++m_totally_free_blocks;
+ block_info_t *c_info = new(mem_address)block_info_t;
+ m_block_multiset.insert(m_block_multiset.end(), *c_info);
+
+ mem_address += HdrSize;
+ //We initialize all Nodes in Node Block to insert
+ //them in the free Node list
+ typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
+ for(size_type i = 0; i < m_real_num_node; ++i){
+ prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *(node_t*)mem_address);
+ mem_address += m_real_node_size;
+ }
+ }
+ }
+
+ void priv_alloc_block(size_type n, AlignOnlyFalse)
+ {
+ size_type real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
+ size_type elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
+ size_type hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+
+ for(size_type i = 0; i != n; ++i){
+ //We allocate a new NodeBlock and put it the last
+ //element of the tree
+ char *mem_address = static_cast<char*>
+ (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
+ if(!mem_address) throw std::bad_alloc();
+ ++m_totally_free_blocks;
+
+ //First initialize header information on the last subblock
+ char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
+ block_info_t *c_info = new(hdr_addr)block_info_t;
+ //Some structural checks
+ BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
+ static_cast<void*>(c_info));
+ typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
+ for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
+ ; subblock < maxsubblock
+ ; ++subblock, mem_address += m_real_block_alignment){
+ //Initialize header offset mark
+ new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+ char *pNode = mem_address + HdrOffsetSize;
+ for(size_type i = 0; i < elements_per_subblock; ++i){
+ prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
+ pNode += m_real_node_size;
+ }
+ }
+ {
+ char *pNode = hdr_addr + HdrSize;
+ //We initialize all Nodes in Node Block to insert
+ //them in the free Node list
+ for(size_type i = 0; i < hdr_subblock_elements; ++i){
+ prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
+ pNode += m_real_node_size;
+ }
+ }
+ //Insert the block after the free node list is full
+ m_block_multiset.insert(m_block_multiset.end(), *c_info);
+ }
+ }
+
+ //!Allocates a block of nodes. Can throw std::bad_alloc
+ void priv_alloc_block(size_type n)
+ { return priv_alloc_block(n, IsAlignOnly()); }
+
+ private:
+ typedef typename boost::pointer_to_other
+ <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
+ const size_type m_max_free_blocks;
+ const size_type m_real_node_size;
+ //Round the size to a power of two value.
+ //This is the total memory size (including payload) that we want to
+ //allocate from the general-purpose allocator
+ const size_type m_real_block_alignment;
+ size_type m_num_subblocks;
+ //This is the real number of nodes per block
+ //const
+ size_type m_real_num_node;
+ segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
+ block_multiset_t m_block_multiset; //Intrusive block list
+ size_type m_totally_free_blocks; //Free blocks
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
Added: branches/release/boost/container/detail/advanced_insert_int.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/advanced_insert_int.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,385 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
+#define BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+#include <boost/move/move.hpp>
+#include <iterator> //std::iterator_traits
+#include <new> //placement new
+#include <boost/assert.hpp>
+
+namespace boost { namespace container { namespace containers_detail {
+
+//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
+template<class T, class Iterator>
+struct advanced_insert_aux_int
+{
+ typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
+ virtual void copy_all_to(Iterator p) = 0;
+ virtual void uninitialized_copy_all_to(Iterator p) = 0;
+ virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
+ virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
+ virtual ~advanced_insert_aux_int() {}
+};
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class FwdIt, class Iterator>
+struct advanced_insert_aux_proxy
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ advanced_insert_aux_proxy(FwdIt first, FwdIt last)
+ : first_(first), last_(last)
+ {}
+
+ virtual ~advanced_insert_aux_proxy()
+ {}
+
+ virtual void copy_all_to(Iterator p)
+ { ::boost::copy_or_move(first_, last_, p); }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ { ::boost::uninitialized_copy_or_move(first_, last_, p); }
+
+ virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ {
+ FwdIt mid = first_;
+ std::advance(mid, division_count);
+ if(first_n){
+ ::boost::uninitialized_copy_or_move(first_, mid, pos);
+ first_ = mid;
+ }
+ else{
+ ::boost::uninitialized_copy_or_move(mid, last_, pos);
+ last_ = mid;
+ }
+ }
+
+ virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ {
+ FwdIt mid = first_;
+ std::advance(mid, division_count);
+ if(first_n){
+ ::boost::copy_or_move(first_, mid, pos);
+ first_ = mid;
+ }
+ else{
+ ::boost::copy_or_move(mid, last_, pos);
+ last_ = mid;
+ }
+ }
+
+ FwdIt first_, last_;
+};
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class Iterator, class SizeType>
+struct default_construct_aux_proxy
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ default_construct_aux_proxy(SizeType count)
+ : count_(count)
+ {}
+
+ void uninitialized_copy_impl(Iterator p, const SizeType n)
+ {
+ BOOST_ASSERT(n <= count_);
+ Iterator orig_p = p;
+ SizeType i = 0;
+ try{
+ for(; i < n; ++i, ++p){
+ new(containers_detail::get_pointer(&*p))T();
+ }
+ }
+ catch(...){
+ while(i--){
+ containers_detail::get_pointer(&*orig_p++)->~T();
+ }
+ throw;
+ }
+ count_ -= n;
+ }
+
+ virtual ~default_construct_aux_proxy()
+ {}
+
+ virtual void copy_all_to(Iterator)
+ { //This should never be called with any count
+ BOOST_ASSERT(count_ == 0);
+ }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ { this->uninitialized_copy_impl(p, count_); }
+
+ virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ {
+ SizeType new_count;
+ if(first_n){
+ new_count = division_count;
+ }
+ else{
+ BOOST_ASSERT(difference_type(count_)>= division_count);
+ new_count = count_ - division_count;
+ }
+ this->uninitialized_copy_impl(pos, new_count);
+ }
+
+ virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
+ {
+ BOOST_ASSERT(count_ == 0);
+ SizeType new_count;
+ if(first_n){
+ new_count = division_count;
+ }
+ else{
+ BOOST_ASSERT(difference_type(count_)>= division_count);
+ new_count = count_ - division_count;
+ }
+ //This function should never called with a count different to zero
+ BOOST_ASSERT(new_count == 0);
+ (void)new_count;
+ }
+
+ SizeType count_;
+};
+
+}}} //namespace boost { namespace container { namespace containers_detail {
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#include <boost/container/detail/variadic_templates_tools.hpp>
+#include <boost/container/detail/stored_ref.hpp>
+#include <boost/move/move.hpp>
+#include <typeinfo>
+//#include <iostream> //For debugging purposes
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class Iterator, class ...Args>
+struct advanced_insert_aux_emplace
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+ explicit advanced_insert_aux_emplace(Args&&... args)
+ : args_(args...)
+ , used_(false)
+ {}
+
+ ~advanced_insert_aux_emplace()
+ {}
+
+ virtual void copy_all_to(Iterator p)
+ { this->priv_copy_all_to(index_tuple_t(), p); }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ { this->priv_uninitialized_copy_all_to(index_tuple_t(), p); }
+
+ virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
+
+ virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ { this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
+
+ private:
+ template<int ...IdxPack>
+ void priv_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
+ {
+ if(!used_){
+ *p = boost::move(T (::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...));
+ used_ = true;
+ }
+ }
+
+ template<int ...IdxPack>
+ void priv_uninitialized_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
+ {
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...);
+ used_ = true;
+ }
+ }
+
+ template<int ...IdxPack>
+ void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
+ {
+ BOOST_ASSERT(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...);
+ used_ = true;
+ }
+ }
+ }
+
+ template<int ...IdxPack>
+ void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
+ {
+ BOOST_ASSERT(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ *p = boost::move(T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...));
+ used_ = true;
+ }
+ }
+ }
+ tuple<Args&...> args_;
+ bool used_;
+};
+
+}}} //namespace boost { namespace container { namespace containers_detail {
+
+#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#include <boost/container/detail/preprocessor.hpp>
+#include <boost/container/detail/value_init.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template<class T, class Iterator>
+struct advanced_insert_aux_emplace
+ : public advanced_insert_aux_int<T, Iterator>
+{
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
+ advanced_insert_aux_emplace()
+ : used_(false)
+ {}
+
+ ~advanced_insert_aux_emplace()
+ {}
+
+ virtual void copy_all_to(Iterator p)
+ {
+ if(!used_){
+ value_init<T>v;
+ *p = boost::move(v.m_t);
+ used_ = true;
+ }
+ }
+
+ virtual void uninitialized_copy_all_to(Iterator p)
+ {
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T();
+ used_ = true;
+ }
+ }
+
+ virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ {
+ BOOST_ASSERT(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ new(containers_detail::get_pointer(&*p))T();
+ used_ = true;
+ }
+ }
+ }
+
+ virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+ {
+ BOOST_ASSERT(division_count <=1);
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+ if(!used_){
+ value_init<T>v;
+ *p = boost::move(v.m_t);
+ used_ = true;
+ }
+ }
+ }
+ private:
+ bool used_;
+};
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<class T, class Iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
+ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ : public advanced_insert_aux_int<T, Iterator> \
+ { \
+ typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type; \
+ \
+ BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
+ : used_(false), BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
+ \
+ virtual void copy_all_to(Iterator p) \
+ { \
+ if(!used_){ \
+ T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ *p = boost::move(v); \
+ used_ = true; \
+ } \
+ } \
+ \
+ virtual void uninitialized_copy_all_to(Iterator p) \
+ { \
+ if(!used_){ \
+ new(containers_detail::get_pointer(&*p))T \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ used_ = true; \
+ } \
+ } \
+ \
+ virtual void uninitialized_copy_some_and_update \
+ (Iterator p, difference_type division_count, bool first_n) \
+ { \
+ BOOST_ASSERT(division_count <=1); \
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
+ if(!used_){ \
+ new(containers_detail::get_pointer(&*p))T \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ used_ = true; \
+ } \
+ } \
+ } \
+ \
+ virtual void copy_some_and_update \
+ (Iterator p, difference_type division_count, bool first_n) \
+ { \
+ BOOST_ASSERT(division_count <=1); \
+ if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
+ if(!used_){ \
+ T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ *p = boost::move(v); \
+ used_ = true; \
+ } \
+ } \
+ } \
+ \
+ bool used_; \
+ BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
+ }; \
+//!
+
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+}}} //namespace boost { namespace container { namespace containers_detail {
+
+#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
Added: branches/release/boost/container/detail/algorithms.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/algorithms.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,215 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
+#define BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/get_pointer.hpp>
+
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/iterators.hpp>
+
+
+#include <cstring>
+
+namespace boost {
+namespace container {
+
+#if defined(BOOST_NO_RVALUE_REFERENCES)
+template<class T>
+struct has_own_construct_from_it
+{
+ static const bool value = false;
+};
+
+namespace containers_detail {
+
+template<class T, class InpIt>
+inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::true_)
+{
+ T::construct(dest, *source);
+}
+
+template<class T, class InpIt>
+inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::false_)
+{
+ new((void*)dest)T(*source);
+}
+
+} //namespace containers_detail {
+
+template<class T, class InpIt>
+inline void construct_in_place(T* dest, InpIt source)
+{
+ typedef containers_detail::bool_<has_own_construct_from_it<T>::value> boolean_t;
+ containers_detail::construct_in_place_impl(dest, source, boolean_t());
+}
+
+#else
+template<class T, class InpIt>
+inline void construct_in_place(T* dest, InpIt source)
+{ ::new((void*)dest)T(*source); }
+#endif
+
+template<class T, class U, class D>
+inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
+{
+ ::new((void*)dest)T();
+}
+
+template<class T, class U, class E, class D>
+inline void construct_in_place(T *dest, emplace_iterator<U, E, D> ei)
+{
+ ei.construct_in_place(dest);
+}
+
+template<class InIt, class OutIt>
+struct optimize_assign
+{
+ static const bool value = false;
+};
+
+template<class T>
+struct optimize_assign<const T*, T*>
+{
+ static const bool value = boost::has_trivial_assign<T>::value;
+};
+
+template<class T>
+struct optimize_assign<T*, T*>
+ : public optimize_assign<const T*, T*>
+{};
+
+template<class InIt, class OutIt>
+struct optimize_copy
+{
+ static const bool value = false;
+};
+
+template<class T>
+struct optimize_copy<const T*, T*>
+{
+ static const bool value = boost::has_trivial_copy<T>::value;
+};
+
+template<class T>
+struct optimize_copy<T*, T*>
+ : public optimize_copy<const T*, T*>
+{};
+
+template<class InIt, class OutIt> inline
+OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, containers_detail::bool_<false>)
+{
+ for (; length--; ++dest, ++first)
+ *dest = *first;
+ return dest;
+}
+
+template<class T> inline
+T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
+{
+ std::size_t size = length*sizeof(T);
+ return (static_cast<T*>(std::memmove(dest, first, size))) + size;
+}
+
+template<class InIt, class OutIt> inline
+OutIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
+{
+ const bool do_optimized_assign = optimize_assign<InIt, OutIt>::value;
+ return copy_n_dispatch(first, length, dest, containers_detail::bool_<do_optimized_assign>());
+}
+
+template<class InIt, class FwdIt> inline
+FwdIt uninitialized_copy_n_dispatch
+ (InIt first,
+ typename std::iterator_traits<InIt>::difference_type count,
+ FwdIt dest, containers_detail::bool_<false>)
+{
+ typedef typename std::iterator_traits<FwdIt>::value_type value_type;
+ //Save initial destination position
+ FwdIt dest_init = dest;
+ typename std::iterator_traits<InIt>::difference_type new_count = count+1;
+
+ BOOST_TRY{
+ //Try to build objects
+ for (; --new_count; ++dest, ++first){
+ construct_in_place(containers_detail::get_pointer(&*dest), first);
+ }
+ }
+ BOOST_CATCH(...){
+ //Call destructors
+ new_count = count - new_count;
+ for (; new_count--; ++dest_init){
+ containers_detail::get_pointer(&*dest_init)->~value_type();
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ return dest;
+}
+template<class T> inline
+T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
+{
+ std::size_t size = length*sizeof(T);
+ return (static_cast<T*>(std::memmove(dest, first, size))) + size;
+}
+
+template<class InIt, class FwdIt> inline
+FwdIt uninitialized_copy_n
+ (InIt first,
+ typename std::iterator_traits<InIt>::difference_type count,
+ FwdIt dest)
+{
+ const bool do_optimized_copy = optimize_copy<InIt, FwdIt>::value;
+ return uninitialized_copy_n_dispatch(first, count, dest, containers_detail::bool_<do_optimized_copy>());
+}
+
+// uninitialized_copy_copy
+// Copies [first1, last1) into [result, result + (last1 - first1)), and
+// copies [first2, last2) into
+// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
+template <class InpIt1, class InpIt2, class FwdIt>
+FwdIt uninitialized_copy_copy
+ (InpIt1 first1, InpIt1 last1, InpIt2 first2, InpIt2 last2, FwdIt result)
+{
+ typedef typename std::iterator_traits<FwdIt>::value_type value_type;
+ FwdIt mid = std::uninitialized_copy(first1, last1, result);
+ BOOST_TRY {
+ return std::uninitialized_copy(first2, last2, mid);
+ }
+ BOOST_CATCH(...){
+ for(;result != mid; ++result){
+ containers_detail::get_pointer(&*result)->~value_type();
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+}
+
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
+
Added: branches/release/boost/container/detail/allocation_type.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/allocation_type.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
+#define BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+namespace boost {
+namespace container {
+
+/// @cond
+enum allocation_type_v
+{
+ // constants for allocation commands
+ allocate_new_v = 0x01,
+ expand_fwd_v = 0x02,
+ expand_bwd_v = 0x04,
+// expand_both = expand_fwd | expand_bwd,
+// expand_or_new = allocate_new | expand_both,
+ shrink_in_place_v = 0x08,
+ nothrow_allocation_v = 0x10,
+ zero_memory_v = 0x20,
+ try_shrink_in_place_v = 0x40
+};
+
+typedef int allocation_type;
+/// @endcond
+static const allocation_type allocate_new = (allocation_type)allocate_new_v;
+static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
+static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
+static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
+static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
+static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
+static const allocation_type zero_memory = (allocation_type)zero_memory_v;
+
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
Added: branches/release/boost/container/detail/config_begin.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/config_begin.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,48 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
+#define BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
+#include <boost/config.hpp>
+
+#endif //BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
+
+#ifdef BOOST_MSVC
+ #ifndef _CRT_SECURE_NO_DEPRECATE
+ #define BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
+ #define _CRT_SECURE_NO_DEPRECATE
+ #endif
+ #pragma warning (push)
+ #pragma warning (disable : 4702) // unreachable code
+ #pragma warning (disable : 4706) // assignment within conditional expression
+ #pragma warning (disable : 4127) // conditional expression is constant
+ #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+ #pragma warning (disable : 4284) // odd return type for operator->
+ #pragma warning (disable : 4244) // possible loss of data
+ #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
+ #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
+ #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
+ #pragma warning (disable : 4355) // "this" : used in base member initializer list
+ #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
+ #pragma warning (disable : 4511) // copy constructor could not be generated
+ #pragma warning (disable : 4512) // assignment operator could not be generated
+ #pragma warning (disable : 4514) // unreferenced inline removed
+ #pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
+ #pragma warning (disable : 4522) // "class" : multiple assignment operators specified
+ #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
+ #pragma warning (disable : 4710) // function not inlined
+ #pragma warning (disable : 4711) // function selected for automatic inline expansion
+ #pragma warning (disable : 4786) // identifier truncated in debug info
+ #pragma warning (disable : 4996) // "function": was declared deprecated
+ #pragma warning (disable : 4197) // top-level volatile in cast is ignored
+ #pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
+ // with /GR-; unpredictable behavior may result
+ #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
+ #pragma warning (disable : 4671) // the copy constructor is inaccessible
+#endif //BOOST_MSVC
Added: branches/release/boost/container/detail/config_end.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/config_end.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,17 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined BOOST_MSVC
+ #pragma warning (pop)
+ #ifdef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
+ #undef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
+ #undef _CRT_SECURE_NO_DEPRECATE
+ #endif
+#endif
+
Added: branches/release/boost/container/detail/destroyers.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/destroyers.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,154 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
+#define BOOST_CONTAINERS_DESTROYERS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/utilities.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an array of objects using a STL allocator.
+template <class Allocator>
+struct scoped_array_deallocator
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::size_type size_type;
+
+ scoped_array_deallocator(pointer p, Allocator& a, size_type length)
+ : m_ptr(p), m_alloc(a), m_length(length) {}
+
+ ~scoped_array_deallocator()
+ { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
+
+ void release()
+ { m_ptr = 0; }
+
+ private:
+ pointer m_ptr;
+ Allocator& m_alloc;
+ size_type m_length;
+};
+
+template <class Allocator>
+struct null_scoped_array_deallocator
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::size_type size_type;
+
+ null_scoped_array_deallocator(pointer, Allocator&, size_type)
+ {}
+
+ void release()
+ {}
+};
+
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template <class Allocator>
+struct scoped_destructor_n
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::value_type value_type;
+ typedef typename Allocator::size_type size_type;
+
+ pointer m_p;
+ size_type m_n;
+
+ scoped_destructor_n(pointer p, size_type n)
+ : m_p(p), m_n(n)
+ {}
+
+ void release()
+ { m_p = 0; }
+
+ void increment_size(size_type inc)
+ { m_n += inc; }
+
+ ~scoped_destructor_n()
+ {
+ if(!m_p) return;
+ value_type *raw_ptr = containers_detail::get_pointer(m_p);
+ for(size_type i = 0; i < m_n; ++i, ++raw_ptr)
+ raw_ptr->~value_type();
+ }
+};
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template <class Allocator>
+struct null_scoped_destructor_n
+{
+ typedef typename Allocator::pointer pointer;
+ typedef typename Allocator::size_type size_type;
+
+ null_scoped_destructor_n(pointer, size_type)
+ {}
+
+ void increment_size(size_type)
+ {}
+
+ void release()
+ {}
+};
+
+template <class A>
+class allocator_destroyer
+{
+ typedef typename A::value_type value_type;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::container::containers_detail::
+ version<A>::value> alloc_version;
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+
+ private:
+ A & a_;
+
+ private:
+ void priv_deallocate(const typename A::pointer &p, allocator_v1)
+ { a_.deallocate(p, 1); }
+
+ void priv_deallocate(const typename A::pointer &p, allocator_v2)
+ { a_.deallocate_one(p); }
+
+ public:
+ allocator_destroyer(A &a)
+ : a_(a)
+ {}
+
+ void operator()(const typename A::pointer &p)
+ {
+ containers_detail::get_pointer(p)->~value_type();
+ priv_deallocate(p, alloc_version());
+ }
+};
+
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
Added: branches/release/boost/container/detail/flat_tree.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/flat_tree.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,858 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_FLAT_TREE_HPP
+#define BOOST_CONTAINERS_FLAT_TREE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/container_fwd.hpp>
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/move/move.hpp>
+
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/container/detail/value_init.hpp>
+#include <boost/container/detail/destroyers.hpp>
+
+namespace boost {
+
+namespace container {
+
+namespace containers_detail {
+
+template<class Compare, class Value, class KeyOfValue>
+class flat_tree_value_compare
+ : private Compare
+{
+ typedef Value first_argument_type;
+ typedef Value second_argument_type;
+ typedef bool return_type;
+ public:
+ flat_tree_value_compare(const Compare &pred)
+ : Compare(pred)
+ {}
+
+ bool operator()(const Value& lhs, const Value& rhs) const
+ {
+ KeyOfValue key_extract;
+ return Compare::operator()(key_extract(lhs), key_extract(rhs));
+ }
+
+ const Compare &get_comp() const
+ { return *this; }
+
+ Compare &get_comp()
+ { return *this; }
+};
+
+template<class Pointer>
+struct get_flat_tree_iterators
+{
+ typedef typename containers_detail::
+ vector_iterator<Pointer> iterator;
+ typedef typename containers_detail::
+ vector_const_iterator<Pointer> const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+};
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+class flat_tree
+{
+ typedef boost::container::vector<Value, A> vector_t;
+ typedef A allocator_t;
+
+ public:
+ typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
+
+ private:
+ struct Data
+ //Inherit from value_compare to do EBO
+ : public value_compare
+ {
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(Data)
+ public:
+ Data(const Data &d)
+ : value_compare(d), m_vect(d.m_vect)
+ {}
+ Data(const Compare &comp,
+ const vector_t &vect)
+ : value_compare(comp), m_vect(vect){}
+
+ Data(const value_compare &comp,
+ const vector_t &vect)
+ : value_compare(comp), m_vect(vect){}
+
+ Data(const Compare &comp,
+ const allocator_t &alloc)
+ : value_compare(comp), m_vect(alloc){}
+
+ Data& operator=(BOOST_COPY_ASSIGN_REF(Data) d)
+ {
+ this->value_compare::operator=(d);
+ m_vect = d.m_vect;
+ return *this;
+ }
+
+ Data& operator=(BOOST_RV_REF(Data) d)
+ {
+ this->value_compare::operator=(boost::move(static_cast<value_compare &>(d)));
+ m_vect = boost::move(d.m_vect);
+ return *this;
+ }
+
+ vector_t m_vect;
+ };
+
+ Data m_data;
+ BOOST_COPYABLE_AND_MOVABLE(flat_tree)
+
+ public:
+
+ typedef typename vector_t::value_type value_type;
+ typedef typename vector_t::pointer pointer;
+ typedef typename vector_t::const_pointer const_pointer;
+ typedef typename vector_t::reference reference;
+ typedef typename vector_t::const_reference const_reference;
+ typedef Key key_type;
+ typedef Compare key_compare;
+ typedef typename vector_t::allocator_type allocator_type;
+ typedef allocator_type stored_allocator_type;
+ typedef typename allocator_type::size_type size_type;
+ typedef typename allocator_type::difference_type difference_type;
+ typedef typename vector_t::iterator iterator;
+ typedef typename vector_t::const_iterator const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+
+ // allocation/deallocation
+ flat_tree(const Compare& comp = Compare(),
+ const allocator_type& a = allocator_type())
+ : m_data(comp, a)
+ { }
+
+ flat_tree(const flat_tree& x)
+ : m_data(x.m_data, x.m_data.m_vect)
+ { }
+
+ flat_tree(BOOST_RV_REF(flat_tree) x)
+ : m_data(boost::move(x.m_data))
+ { }
+
+ template <class InputIterator>
+ flat_tree( ordered_range_t, InputIterator first, InputIterator last
+ , const Compare& comp = Compare()
+ , const allocator_type& a = allocator_type())
+ : m_data(comp, a)
+ { this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
+
+ ~flat_tree()
+ { }
+
+ flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
+ { m_data = x.m_data; return *this; }
+
+ flat_tree& operator=(BOOST_RV_REF(flat_tree) mx)
+ { m_data = boost::move(mx.m_data); return *this; }
+
+ public:
+ // accessors:
+ Compare key_comp() const
+ { return this->m_data.get_comp(); }
+
+ allocator_type get_allocator() const
+ { return this->m_data.m_vect.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->m_data.m_vect.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->m_data.m_vect.get_stored_allocator(); }
+
+ iterator begin()
+ { return this->m_data.m_vect.begin(); }
+
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ const_iterator cbegin() const
+ { return this->m_data.m_vect.begin(); }
+
+ iterator end()
+ { return this->m_data.m_vect.end(); }
+
+ const_iterator end() const
+ { return this->cend(); }
+
+ const_iterator cend() const
+ { return this->m_data.m_vect.end(); }
+
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->end()); }
+
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->cend()); }
+
+ reverse_iterator rend()
+ { return reverse_iterator(this->begin()); }
+
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->cbegin()); }
+
+ bool empty() const
+ { return this->m_data.m_vect.empty(); }
+
+ size_type size() const
+ { return this->m_data.m_vect.size(); }
+
+ size_type max_size() const
+ { return this->m_data.m_vect.max_size(); }
+
+ void swap(flat_tree& other)
+ {
+ value_compare& mycomp = this->m_data;
+ value_compare& othercomp = other.m_data;
+ containers_detail::do_swap(mycomp, othercomp);
+ vector_t & myvect = this->m_data.m_vect;
+ vector_t & othervect = other.m_data.m_vect;
+ myvect.swap(othervect);
+ }
+
+ public:
+ // insert/erase
+ std::pair<iterator,bool> insert_unique(const value_type& val)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, val);
+ }
+ return ret;
+ }
+
+ std::pair<iterator,bool> insert_unique(BOOST_RV_REF(value_type) val)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::move(val));
+ }
+ return ret;
+ }
+
+
+ iterator insert_equal(const value_type& val)
+ {
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, val);
+ return i;
+ }
+
+ iterator insert_equal(BOOST_RV_REF(value_type) mval)
+ {
+ iterator i = this->upper_bound(KeyOfValue()(mval));
+ i = this->m_data.m_vect.insert(i, boost::move(mval));
+ return i;
+ }
+
+ iterator insert_unique(const_iterator pos, const value_type& val)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, val);
+ }
+ return ret.first;
+ }
+
+ iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) mval)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::move(mval));
+ }
+ return ret.first;
+ }
+
+ iterator insert_equal(const_iterator pos, const value_type& val)
+ {
+ insert_commit_data data;
+ priv_insert_equal_prepare(pos, val, data);
+ return priv_insert_commit(data, val);
+ }
+
+ iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
+ {
+ insert_commit_data data;
+ priv_insert_equal_prepare(pos, mval, data);
+ return priv_insert_commit(data, boost::move(mval));
+ }
+
+ template <class InIt>
+ void insert_unique(InIt first, InIt last)
+ {
+ for ( ; first != last; ++first)
+ this->insert_unique(*first);
+ }
+
+ template <class InIt>
+ void insert_equal(InIt first, InIt last)
+ {
+ typedef typename
+ std::iterator_traits<InIt>::iterator_category ItCat;
+ priv_insert_equal(first, last, ItCat());
+ }
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template <class... Args>
+ iterator emplace_unique(Args&&... args)
+ {
+ value_type && val = value_type(boost::forward<Args>(args)...);
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::move(val));
+ }
+ return ret.first;
+ }
+
+ template <class... Args>
+ iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ {
+ value_type && val = value_type(boost::forward<Args>(args)...);
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::move(val));
+ }
+ return ret.first;
+ }
+
+ template <class... Args>
+ iterator emplace_equal(Args&&... args)
+ {
+ value_type &&val = value_type(boost::forward<Args>(args)...);
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, boost::move(val));
+ return i;
+ }
+
+ template <class... Args>
+ iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ {
+ value_type &&val = value_type(boost::forward<Args>(args)...);
+ insert_commit_data data;
+ priv_insert_equal_prepare(hint, val, data);
+ return priv_insert_commit(data, boost::move(val));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace_unique()
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::move(val));
+ }
+ return ret.first;
+ }
+
+ iterator emplace_hint_unique(const_iterator hint)
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, boost::move(val));
+ }
+ return ret.first;
+ }
+
+ iterator emplace_equal()
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, boost::move(val));
+ return i;
+ }
+
+ iterator emplace_hint_equal(const_iterator hint)
+ {
+ containers_detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ priv_insert_equal_prepare(hint, val, data);
+ return priv_insert_commit(data, boost::move(val));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
+ if(ret.second){ \
+ ret.first = priv_insert_commit(data, boost::move(val)); \
+ } \
+ return ret.first; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_unique(const_iterator hint, \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
+ if(ret.second){ \
+ ret.first = priv_insert_commit(data, boost::move(val)); \
+ } \
+ return ret.first; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ iterator i = this->upper_bound(KeyOfValue()(val)); \
+ i = this->m_data.m_vect.insert(i, boost::move(val)); \
+ return i; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_equal(const_iterator hint, \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ priv_insert_equal_prepare(hint, val, data); \
+ return priv_insert_commit(data, boost::move(val)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator erase(const_iterator position)
+ { return this->m_data.m_vect.erase(position); }
+
+ size_type erase(const key_type& k)
+ {
+ std::pair<iterator,iterator > itp = this->equal_range(k);
+ size_type ret = static_cast<size_type>(itp.second-itp.first);
+ if (ret){
+ this->m_data.m_vect.erase(itp.first, itp.second);
+ }
+ return ret;
+ }
+
+ iterator erase(const_iterator first, const_iterator last)
+ { return this->m_data.m_vect.erase(first, last); }
+
+ void clear()
+ { this->m_data.m_vect.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { this->m_data.m_vect.shrink_to_fit(); }
+
+ // set operations:
+ iterator find(const key_type& k)
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ iterator i = this->lower_bound(k);
+
+ if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
+ i = this->end();
+ }
+ return i;
+ }
+
+ const_iterator find(const key_type& k) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ const_iterator i = this->lower_bound(k);
+
+ if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
+ i = this->end();
+ }
+ return i;
+ }
+
+ size_type count(const key_type& k) const
+ {
+ std::pair<const_iterator, const_iterator> p = this->equal_range(k);
+ size_type n = p.second - p.first;
+ return n;
+ }
+
+ iterator lower_bound(const key_type& k)
+ { return this->priv_lower_bound(this->begin(), this->end(), k); }
+
+ const_iterator lower_bound(const key_type& k) const
+ { return this->priv_lower_bound(this->begin(), this->end(), k); }
+
+ iterator upper_bound(const key_type& k)
+ { return this->priv_upper_bound(this->begin(), this->end(), k); }
+
+ const_iterator upper_bound(const key_type& k) const
+ { return this->priv_upper_bound(this->begin(), this->end(), k); }
+
+ std::pair<iterator,iterator> equal_range(const key_type& k)
+ { return this->priv_equal_range(this->begin(), this->end(), k); }
+
+ std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
+ { return this->priv_equal_range(this->begin(), this->end(), k); }
+
+ size_type capacity() const
+ { return this->m_data.m_vect.capacity(); }
+
+ void reserve(size_type count)
+ { this->m_data.m_vect.reserve(count); }
+
+ private:
+ struct insert_commit_data
+ {
+ const_iterator position;
+ };
+
+ // insert/erase
+ void priv_insert_equal_prepare
+ (const_iterator pos, const value_type& val, insert_commit_data &data)
+ {
+ // N1780
+ // To insert val at pos:
+ // if pos == end || val <= *pos
+ // if pos == begin || val >= *(pos-1)
+ // insert val before pos
+ // else
+ // insert val before upper_bound(val)
+ // else if pos+1 == end || val <= *(pos+1)
+ // insert val after pos
+ // else
+ // insert val before lower_bound(val)
+ const value_compare &value_comp = this->m_data;
+
+ if(pos == this->cend() || !value_comp(*pos, val)){
+ if (pos == this->cbegin() || !value_comp(val, pos[-1])){
+ data.position = pos;
+ }
+ else{
+ data.position =
+ this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
+ }
+ }
+ //Works, but increases code complexity
+ //else if (++pos == this->end() || !value_comp(*pos, val)){
+ // return this->m_data.m_vect.insert(pos, val);
+ //}
+ else{
+ data.position =
+ this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
+ }
+ }
+
+ std::pair<iterator,bool> priv_insert_unique_prepare
+ (const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
+ {
+ const value_compare &value_comp = this->m_data;
+ commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
+ return std::pair<iterator,bool>
+ ( *reinterpret_cast<iterator*>(&commit_data.position)
+ , commit_data.position == end || value_comp(val, *commit_data.position));
+ }
+
+ std::pair<iterator,bool> priv_insert_unique_prepare
+ (const value_type& val, insert_commit_data &commit_data)
+ { return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
+
+ std::pair<iterator,bool> priv_insert_unique_prepare
+ (const_iterator pos, const value_type& val, insert_commit_data &commit_data)
+ {
+ //N1780. Props to Howard Hinnant!
+ //To insert val at pos:
+ //if pos == end || val <= *pos
+ // if pos == begin || val >= *(pos-1)
+ // insert val before pos
+ // else
+ // insert val before upper_bound(val)
+ //else if pos+1 == end || val <= *(pos+1)
+ // insert val after pos
+ //else
+ // insert val before lower_bound(val)
+ const value_compare &value_comp = this->m_data;
+
+ if(pos == this->cend() || value_comp(val, *pos)){
+ if(pos != this->cbegin() && !value_comp(val, pos[-1])){
+ if(value_comp(pos[-1], val)){
+ commit_data.position = pos;
+ return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
+ }
+ else{
+ return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
+ }
+ }
+ return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
+ }
+
+ // Works, but increases code complexity
+ //Next check
+ //else if (value_comp(*pos, val) && !value_comp(pos[1], val)){
+ // if(value_comp(val, pos[1])){
+ // commit_data.position = pos+1;
+ // return std::pair<iterator,bool>(pos+1, true);
+ // }
+ // else{
+ // return std::pair<iterator,bool>(pos+1, false);
+ // }
+ //}
+ else{
+ //[... pos ... val ... ]
+ //The hint is before the insertion position, so insert it
+ //in the remaining range
+ return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data);
+ }
+ }
+
+ template<class Convertible>
+ iterator priv_insert_commit
+ (insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible)
+ {
+ return this->m_data.m_vect.insert
+ ( commit_data.position
+ , boost::forward<Convertible>(convertible));
+ }
+
+ template <class RanIt>
+ RanIt priv_lower_bound(RanIt first, RanIt last,
+ const key_type & key) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ KeyOfValue key_extract;
+ difference_type len = last - first, half;
+ RanIt middle;
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+ middle += half;
+
+ if (key_comp(key_extract(*middle), key)) {
+ ++middle;
+ first = middle;
+ len = len - half - 1;
+ }
+ else
+ len = half;
+ }
+ return first;
+ }
+
+ template <class RanIt>
+ RanIt priv_upper_bound(RanIt first, RanIt last,
+ const key_type & key) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ KeyOfValue key_extract;
+ difference_type len = last - first, half;
+ RanIt middle;
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+ middle += half;
+
+ if (key_comp(key, key_extract(*middle))) {
+ len = half;
+ }
+ else{
+ first = ++middle;
+ len = len - half - 1;
+ }
+ }
+ return first;
+ }
+
+ template <class RanIt>
+ std::pair<RanIt, RanIt>
+ priv_equal_range(RanIt first, RanIt last, const key_type& key) const
+ {
+ const Compare &key_comp = this->m_data.get_comp();
+ KeyOfValue key_extract;
+ difference_type len = last - first, half;
+ RanIt middle, left, right;
+
+ while (len > 0) {
+ half = len >> 1;
+ middle = first;
+ middle += half;
+
+ if (key_comp(key_extract(*middle), key)){
+ first = middle;
+ ++first;
+ len = len - half - 1;
+ }
+ else if (key_comp(key, key_extract(*middle))){
+ len = half;
+ }
+ else {
+ left = this->priv_lower_bound(first, middle, key);
+ first += len;
+ right = this->priv_upper_bound(++middle, first, key);
+ return std::pair<RanIt, RanIt>(left, right);
+ }
+ }
+ return std::pair<RanIt, RanIt>(first, first);
+ }
+
+ template <class FwdIt>
+ void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = static_cast<size_type>(std::distance(first, last));
+ this->reserve(this->size()+len);
+ this->priv_insert_equal(first, last, std::input_iterator_tag());
+ }
+
+ template <class InIt>
+ void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
+ {
+ for ( ; first != last; ++first)
+ this->insert_equal(*first);
+ }
+
+/*
+ template <class FwdIt>
+ void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = static_cast<size_type>(std::distance(first, last));
+ this->reserve(this->size()+len);
+ priv_insert_unique(first, last, std::input_iterator_tag());
+ }
+
+ template <class InIt>
+ void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag)
+ {
+ for ( ; first != last; ++first)
+ this->insert_unique(*first);
+ }
+*/
+};
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline bool
+operator==(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+{
+ return x.size() == y.size() &&
+ std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline bool
+operator<(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(),
+ y.begin(), y.end());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline bool
+operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+ { return !(x == y); }
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline bool
+operator>(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+ { return y < x; }
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline bool
+operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+ { return !(y < x); }
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline bool
+operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ const flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+ { return !(x < y); }
+
+
+template <class Key, class Value, class KeyOfValue,
+ class Compare, class A>
+inline void
+swap(flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
+ flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
+ { x.swap(y); }
+
+} //namespace containers_detail {
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class V, class KOV,
+class C, class A>
+struct has_trivial_destructor_after_move<boost::container::containers_detail::flat_tree<K, V, KOV, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_FLAT_TREE_HPP
Added: branches/release/boost/container/detail/iterators.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/iterators.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,546 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
+#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+#include <boost/move/move.hpp>
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/container/detail/variadic_templates_tools.hpp>
+#include <boost/container/detail/stored_ref.hpp>
+#else
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+#include <iterator>
+
+namespace boost {
+namespace container {
+
+template <class T, class Difference = std::ptrdiff_t>
+class constant_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+ typedef constant_iterator<T, Difference> this_type;
+
+ public:
+ explicit constant_iterator(const T &ref, Difference range_size)
+ : m_ptr(&ref), m_num(range_size){}
+
+ //Constructors
+ constant_iterator()
+ : m_ptr(0), m_num(0){}
+
+ constant_iterator& operator++()
+ { increment(); return *this; }
+
+ constant_iterator operator++(int)
+ {
+ constant_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ constant_iterator& operator--()
+ { decrement(); return *this; }
+
+ constant_iterator operator--(int)
+ {
+ constant_iterator result (*this);
+ decrement();
+ return result;
+ }
+
+ friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ constant_iterator& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ constant_iterator operator+(Difference off) const
+ {
+ constant_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend constant_iterator operator+(Difference off, const constant_iterator& right)
+ { return right + off; }
+
+ constant_iterator& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ constant_iterator operator-(Difference off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T& operator[] (Difference n) const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ private:
+ const T * m_ptr;
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ { return *m_ptr; }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template <class T, class Difference = std::ptrdiff_t>
+class default_construct_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+ typedef default_construct_iterator<T, Difference> this_type;
+
+ public:
+ explicit default_construct_iterator(Difference range_size)
+ : m_num(range_size){}
+
+ //Constructors
+ default_construct_iterator()
+ : m_num(0){}
+
+ default_construct_iterator& operator++()
+ { increment(); return *this; }
+
+ default_construct_iterator operator++(int)
+ {
+ default_construct_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ default_construct_iterator& operator--()
+ { decrement(); return *this; }
+
+ default_construct_iterator operator--(int)
+ {
+ default_construct_iterator result (*this);
+ decrement();
+ return result;
+ }
+
+ friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ default_construct_iterator& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ default_construct_iterator operator+(Difference off) const
+ {
+ default_construct_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
+ { return right + off; }
+
+ default_construct_iterator& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ default_construct_iterator operator-(Difference off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ const T& operator[] (Difference n) const
+ { return dereference(); }
+
+ private:
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ {
+ static T dummy;
+ return dummy;
+ }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template <class T, class Difference = std::ptrdiff_t>
+class repeat_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference>
+{
+ typedef repeat_iterator<T, Difference> this_type;
+ public:
+ explicit repeat_iterator(T &ref, Difference range_size)
+ : m_ptr(&ref), m_num(range_size){}
+
+ //Constructors
+ repeat_iterator()
+ : m_ptr(0), m_num(0){}
+
+ this_type& operator++()
+ { increment(); return *this; }
+
+ this_type operator++(int)
+ {
+ this_type result (*this);
+ increment();
+ return result;
+ }
+
+ this_type& operator--()
+ { increment(); return *this; }
+
+ this_type operator--(int)
+ {
+ this_type result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const this_type& i, const this_type& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const this_type& i, const this_type& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const this_type& i, const this_type& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const this_type& i, const this_type& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const this_type& i, const this_type& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const this_type& i, const this_type& i2)
+ { return !(i < i2); }
+
+ friend Difference operator- (const this_type& i, const this_type& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ this_type& operator+=(Difference off)
+ { this->advance(off); return *this; }
+
+ this_type operator+(Difference off) const
+ {
+ this_type other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend this_type operator+(Difference off, const this_type& right)
+ { return right + off; }
+
+ this_type& operator-=(Difference off)
+ { this->advance(-off); return *this; }
+
+ this_type operator-(Difference off) const
+ { return *this + (-off); }
+
+ T& operator*() const
+ { return dereference(); }
+
+ T& operator[] (Difference n) const
+ { return dereference(); }
+
+ T *operator->() const
+ { return &(dereference()); }
+
+ private:
+ T * m_ptr;
+ Difference m_num;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ T & dereference() const
+ { return *m_ptr; }
+
+ void advance(Difference n)
+ { m_num -= n; }
+
+ Difference distance_to(const this_type &other)const
+ { return m_num - other.m_num; }
+};
+
+template <class T, class E, class Difference /*= std::ptrdiff_t*/>
+class emplace_iterator
+ : public std::iterator
+ <std::random_access_iterator_tag, T, Difference, const T*, const T &>
+{
+ typedef emplace_iterator this_type;
+
+ public:
+ typedef Difference difference_type;
+ explicit emplace_iterator(E&e)
+ : m_num(1), m_pe(&e){}
+
+ emplace_iterator()
+ : m_num(0), m_pe(0){}
+
+ this_type& operator++()
+ { increment(); return *this; }
+
+ this_type operator++(int)
+ {
+ this_type result (*this);
+ increment();
+ return result;
+ }
+
+ this_type& operator--()
+ { decrement(); return *this; }
+
+ this_type operator--(int)
+ {
+ this_type result (*this);
+ decrement();
+ return result;
+ }
+
+ friend bool operator== (const this_type& i, const this_type& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const this_type& i, const this_type& i2)
+ { return !(i == i2); }
+
+ friend bool operator< (const this_type& i, const this_type& i2)
+ { return i.less(i2); }
+
+ friend bool operator> (const this_type& i, const this_type& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const this_type& i, const this_type& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const this_type& i, const this_type& i2)
+ { return !(i < i2); }
+
+ friend difference_type operator- (const this_type& i, const this_type& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ this_type& operator+=(difference_type off)
+ { this->advance(off); return *this; }
+
+ this_type operator+(difference_type off) const
+ {
+ this_type other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend this_type operator+(difference_type off, const this_type& right)
+ { return right + off; }
+
+ this_type& operator-=(difference_type off)
+ { this->advance(-off); return *this; }
+
+ this_type operator-(difference_type off) const
+ { return *this + (-off); }
+
+ const T& operator*() const
+ { return dereference(); }
+
+ const T& operator[](difference_type) const
+ { return dereference(); }
+
+ const T* operator->() const
+ { return &(dereference()); }
+
+ void construct_in_place(T* ptr)
+ { (*m_pe)(ptr); }
+
+ private:
+ difference_type m_num;
+ E * m_pe;
+
+ void increment()
+ { --m_num; }
+
+ void decrement()
+ { ++m_num; }
+
+ bool equal(const this_type &other) const
+ { return m_num == other.m_num; }
+
+ bool less(const this_type &other) const
+ { return other.m_num < m_num; }
+
+ const T & dereference() const
+ {
+ static T dummy;
+ return dummy;
+ }
+
+ void advance(difference_type n)
+ { m_num -= n; }
+
+ difference_type distance_to(const this_type &other)const
+ { return difference_type(m_num - other.m_num); }
+};
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+template<class T, class ...Args>
+struct emplace_functor
+{
+ typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+ emplace_functor(Args&&... args)
+ : args_(args...)
+ {}
+
+ void operator()(T *ptr)
+ { emplace_functor::inplace_impl(ptr, index_tuple_t()); }
+
+ template<int ...IdxPack>
+ void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
+ { ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); }
+
+ containers_detail::tuple<Args&...> args_;
+};
+
+#else
+
+template<class T>
+struct emplace_functor
+{
+ emplace_functor()
+ {}
+ void operator()(T *ptr)
+ { new(ptr) T(); }
+};
+
+#define BOOST_PP_LOCAL_MACRO(n) \
+ template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \
+ struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ { \
+ BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
+ : BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
+ \
+ void operator()(T *ptr) \
+ { \
+ new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
+ } \
+ BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
+ }; \
+ //!
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#endif
+
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
+
Added: branches/release/boost/container/detail/math_functions.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/math_functions.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,113 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Stephen Cleary 2000.
+// (C) Copyright Ion Gaztanaga 2007-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+// This file is a slightly modified file from Boost.Pool
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+
+#include "config_begin.hpp"
+#include <climits>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+// Greatest common divisor and least common multiple
+
+//
+// gcd is an algorithm that calculates the greatest common divisor of two
+// integers, using Euclid's algorithm.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer gcd(Integer A, Integer B)
+{
+ do
+ {
+ const Integer tmp(B);
+ B = A % B;
+ A = tmp;
+ } while (B != 0);
+
+ return A;
+}
+
+//
+// lcm is an algorithm that calculates the least common multiple of two
+// integers.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer lcm(const Integer & A, const Integer & B)
+{
+ Integer ret = A;
+ ret /= gcd(A, B);
+ ret *= B;
+ return ret;
+}
+
+template <typename Integer>
+inline Integer log2_ceil(const Integer & A)
+{
+ Integer i = 0;
+ Integer power_of_2 = 1;
+
+ while(power_of_2 < A){
+ power_of_2 <<= 1;
+ ++i;
+ }
+ return i;
+}
+
+template <typename Integer>
+inline Integer upper_power_of_2(const Integer & A)
+{
+ Integer power_of_2 = 1;
+
+ while(power_of_2 < A){
+ power_of_2 <<= 1;
+ }
+ return power_of_2;
+}
+
+//This function uses binary search to discover the
+//highest set bit of the integer
+inline std::size_t floor_log2 (std::size_t x)
+{
+ const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
+ const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
+ BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
+
+ std::size_t n = x;
+ std::size_t log2 = 0;
+
+ for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
+ std::size_t tmp = n >> shift;
+ if (tmp)
+ log2 += shift, n = tmp;
+ }
+
+ return log2;
+}
+
+} // namespace containers_detail
+} // namespace container
+} // namespace boost
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif
Added: branches/release/boost/container/detail/mpl.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/mpl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,155 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
+#define BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template <class T, T val>
+struct integral_constant
+{
+ static const T value = val;
+ typedef integral_constant<T,val> type;
+};
+
+template< bool C_ >
+struct bool_ : integral_constant<bool, C_>
+{
+ static const bool value = C_;
+};
+
+typedef bool_<true> true_;
+typedef bool_<false> false_;
+
+typedef true_ true_type;
+typedef false_ false_type;
+
+typedef char yes_type;
+struct no_type
+{
+ char padding[8];
+};
+
+template <bool B, class T = void>
+struct enable_if_c {
+ typedef T type;
+};
+
+template <class T>
+struct enable_if_c<false, T> {};
+
+template <class Cond, class T = void>
+struct enable_if : public enable_if_c<Cond::value, T> {};
+
+template <class Cond, class T = void>
+struct disable_if : public enable_if_c<!Cond::value, T> {};
+
+template <bool B, class T = void>
+struct disable_if_c : public enable_if_c<!B, T> {};
+
+template <class T, class U>
+class is_convertible
+{
+ typedef char true_t;
+ class false_t { char dummy[2]; };
+ static true_t dispatch(U);
+ static false_t dispatch(...);
+ static T trigger();
+ public:
+ enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+};
+
+template<
+ bool C
+ , typename T1
+ , typename T2
+ >
+struct if_c
+{
+ typedef T1 type;
+};
+
+template<
+ typename T1
+ , typename T2
+ >
+struct if_c<false,T1,T2>
+{
+ typedef T2 type;
+};
+
+template<
+ typename T1
+ , typename T2
+ , typename T3
+ >
+struct if_
+{
+ typedef typename if_c<0 != T1::value, T2, T3>::type type;
+};
+
+
+template <class Pair>
+struct select1st
+// : public std::unary_function<Pair, typename Pair::first_type>
+{
+ template<class OtherPair>
+ const typename Pair::first_type& operator()(const OtherPair& x) const
+ { return x.first; }
+
+ const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
+ { return x; }
+};
+
+// identity is an extension: it is not part of the standard.
+template <class T>
+struct identity
+// : public std::unary_function<T,T>
+{
+ typedef T type;
+ const T& operator()(const T& x) const
+ { return x; }
+};
+
+template<std::size_t S>
+struct ls_zeros
+{
+ static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
+};
+
+template<>
+struct ls_zeros<0>
+{
+ static const std::size_t value = 0;
+};
+
+template<>
+struct ls_zeros<1>
+{
+ static const std::size_t value = 0;
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
+
Added: branches/release/boost/container/detail/multiallocation_chain.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/multiallocation_chain.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,252 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
+#define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
+
+#include "config_begin.hpp"
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/transform_iterator.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/move/move.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class VoidPointer>
+class basic_multiallocation_chain
+{
+ private:
+ typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
+ ,bi::link_mode<bi::normal_link>
+ > node;
+
+ typedef typename boost::pointer_to_other<VoidPointer, char>::type char_ptr;
+ typedef typename std::iterator_traits<char_ptr>::difference_type difference_type;
+
+ typedef bi::slist< node
+ , bi::linear<true>
+ , bi::cache_last<true>
+ , bi::size_type<typename boost::make_unsigned<difference_type>::type>
+ > slist_impl_t;
+ slist_impl_t slist_impl_;
+
+ static node & to_node(VoidPointer p)
+ { return *static_cast<node*>(static_cast<void*>(containers_detail::get_pointer(p))); }
+
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
+
+ public:
+
+
+ typedef VoidPointer void_pointer;
+ typedef typename slist_impl_t::iterator iterator;
+ typedef typename slist_impl_t::size_type size_type;
+
+ basic_multiallocation_chain()
+ : slist_impl_()
+ {}
+
+ basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
+ : slist_impl_()
+ { slist_impl_.swap(other.slist_impl_); }
+
+ basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
+ {
+ basic_multiallocation_chain tmp(boost::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ bool empty() const
+ { return slist_impl_.empty(); }
+
+ size_type size() const
+ { return slist_impl_.size(); }
+
+ iterator before_begin()
+ { return slist_impl_.before_begin(); }
+
+ iterator begin()
+ { return slist_impl_.begin(); }
+
+ iterator end()
+ { return slist_impl_.end(); }
+
+ iterator last()
+ { return slist_impl_.last(); }
+
+ void clear()
+ { slist_impl_.clear(); }
+
+ iterator insert_after(iterator it, void_pointer m)
+ { return slist_impl_.insert_after(it, to_node(m)); }
+
+ void push_front(void_pointer m)
+ { return slist_impl_.push_front(to_node(m)); }
+
+ void push_back(void_pointer m)
+ { return slist_impl_.push_back(to_node(m)); }
+
+ void pop_front()
+ { return slist_impl_.pop_front(); }
+
+ void *front()
+ { return &*slist_impl_.begin(); }
+
+ void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
+ { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); }
+
+ void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n)
+ { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end, n); }
+
+ void splice_after(iterator after_this, basic_multiallocation_chain &x)
+ { slist_impl_.splice_after(after_this, x.slist_impl_); }
+
+ void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
+ { slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end)); }
+
+ void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
+ { slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n); }
+
+ void swap(basic_multiallocation_chain &x)
+ { slist_impl_.swap(x.slist_impl_); }
+
+ static iterator iterator_to(void_pointer p)
+ { return slist_impl_t::s_iterator_to(to_node(p)); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ {
+ std::pair<void_pointer, void_pointer> ret
+ (slist_impl_.begin().operator->()
+ ,slist_impl_.last().operator->());
+ slist_impl_.clear();
+ return ret;
+ }
+};
+
+template<class T>
+struct cast_functor
+{
+ typedef typename containers_detail::add_reference<T>::type result_type;
+ template<class U>
+ result_type operator()(U &ptr) const
+ { return *static_cast<T*>(static_cast<void*>(&ptr)); }
+};
+
+template<class MultiallocationChain, class T>
+class transform_multiallocation_chain
+{
+ private:
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
+
+ MultiallocationChain holder_;
+ typedef typename MultiallocationChain::void_pointer void_pointer;
+ typedef typename boost::pointer_to_other
+ <void_pointer, T>::type pointer;
+
+ static pointer cast(void_pointer p)
+ {
+ return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
+ }
+
+ public:
+ typedef transform_iterator
+ < typename MultiallocationChain::iterator
+ , containers_detail::cast_functor <T> > iterator;
+ typedef typename MultiallocationChain::size_type size_type;
+
+ transform_multiallocation_chain()
+ : holder_()
+ {}
+
+ transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
+ : holder_()
+ { this->swap(other); }
+
+ transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
+ : holder_(boost::move(other))
+ {}
+
+ transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
+ {
+ transform_multiallocation_chain tmp(boost::move(other));
+ this->swap(tmp);
+ return *this;
+ }
+
+ void push_front(pointer mem)
+ { holder_.push_front(mem); }
+
+ void swap(transform_multiallocation_chain &other_chain)
+ { holder_.swap(other_chain.holder_); }
+
+ void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n)
+ { holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
+
+ void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
+ { holder_.incorporate_after(after_this.base(), begin, before_end, n); }
+
+ void pop_front()
+ { holder_.pop_front(); }
+
+ pointer front()
+ { return cast(holder_.front()); }
+
+ bool empty() const
+ { return holder_.empty(); }
+
+ iterator before_begin()
+ { return iterator(holder_.before_begin()); }
+
+ iterator begin()
+ { return iterator(holder_.begin()); }
+
+ iterator end()
+ { return iterator(holder_.end()); }
+
+ iterator last()
+ { return iterator(holder_.last()); }
+
+ size_type size() const
+ { return holder_.size(); }
+
+ void clear()
+ { holder_.clear(); }
+
+ iterator insert_after(iterator it, pointer m)
+ { return iterator(holder_.insert_after(it.base(), m)); }
+
+ static iterator iterator_to(pointer p)
+ { return iterator(MultiallocationChain::iterator_to(p)); }
+
+ std::pair<void_pointer, void_pointer> extract_data()
+ { return holder_.extract_data(); }
+
+ MultiallocationChain extract_multiallocation_chain()
+ {
+ return MultiallocationChain(boost::move(holder_));
+ }
+};
+
+}}}
+
+// namespace containers_detail {
+// namespace container {
+// namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
Added: branches/release/boost/container/detail/node_alloc_holder.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/node_alloc_holder.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,501 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
+#define BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+#include <utility>
+#include <functional>
+
+#include <boost/move/move.hpp>
+#include <boost/intrusive/options.hpp>
+
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/destroyers.hpp>
+
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+#include <boost/container/detail/algorithms.hpp>
+
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an object using a STL allocator.
+template <class Allocator>
+struct scoped_deallocator
+{
+ typedef typename Allocator::pointer pointer;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::container::containers_detail::
+ version<Allocator>::value> alloc_version;
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+
+ private:
+ void priv_deallocate(allocator_v1)
+ { m_alloc.deallocate(m_ptr, 1); }
+
+ void priv_deallocate(allocator_v2)
+ { m_alloc.deallocate_one(m_ptr); }
+
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
+
+ public:
+
+ pointer m_ptr;
+ Allocator& m_alloc;
+
+ scoped_deallocator(pointer p, Allocator& a)
+ : m_ptr(p), m_alloc(a)
+ {}
+
+ ~scoped_deallocator()
+ { if (m_ptr)priv_deallocate(alloc_version()); }
+
+ scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
+ : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
+ { o.release(); }
+
+ pointer get() const
+ { return m_ptr; }
+
+ void release()
+ { m_ptr = 0; }
+};
+
+template <class A>
+class allocator_destroyer_and_chain_builder
+{
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_chain multiallocation_chain;
+
+ A & a_;
+ multiallocation_chain &c_;
+
+ public:
+ allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
+ : a_(a), c_(c)
+ {}
+
+ void operator()(const typename A::pointer &p)
+ {
+ value_type *vp = containers_detail::get_pointer(p);
+ vp->~value_type();
+ c_.push_front(vp);
+ }
+};
+
+template <class A>
+class allocator_multialloc_chain_node_deallocator
+{
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_chain multiallocation_chain;
+ typedef allocator_destroyer_and_chain_builder<A> chain_builder;
+
+ A & a_;
+ multiallocation_chain c_;
+
+ public:
+ allocator_multialloc_chain_node_deallocator(A &a)
+ : a_(a), c_()
+ {}
+
+ chain_builder get_chain_builder()
+ { return chain_builder(a_, c_); }
+
+ ~allocator_multialloc_chain_node_deallocator()
+ {
+ if(!c_.empty())
+ a_.deallocate_individual(boost::move(c_));
+ }
+};
+
+
+template<class ValueCompare, class Node>
+struct node_compare
+ : private ValueCompare
+{
+ typedef typename ValueCompare::key_type key_type;
+ typedef typename ValueCompare::value_type value_type;
+ typedef typename ValueCompare::key_of_value key_of_value;
+
+ node_compare(const ValueCompare &pred)
+ : ValueCompare(pred)
+ {}
+
+ ValueCompare &value_comp()
+ { return static_cast<ValueCompare &>(*this); }
+
+ ValueCompare &value_comp() const
+ { return static_cast<const ValueCompare &>(*this); }
+
+ bool operator()(const Node &a, const Node &b) const
+ { return ValueCompare::operator()(a.get_data(), b.get_data()); }
+};
+
+template<class A, class ICont>
+struct node_alloc_holder
+{
+ typedef node_alloc_holder<A, ICont> self_t;
+ typedef typename A::value_type value_type;
+ typedef typename ICont::value_type Node;
+ typedef typename A::template rebind<Node>::other NodeAlloc;
+ typedef A ValAlloc;
+ typedef typename NodeAlloc::pointer NodePtr;
+ typedef containers_detail::scoped_deallocator<NodeAlloc> Deallocator;
+ typedef typename NodeAlloc::size_type size_type;
+ typedef typename NodeAlloc::difference_type difference_type;
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::container::containers_detail::
+ version<NodeAlloc>::value> alloc_version;
+ typedef typename ICont::iterator icont_iterator;
+ typedef typename ICont::const_iterator icont_citerator;
+ typedef allocator_destroyer<NodeAlloc> Destroyer;
+
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
+
+ public:
+
+ node_alloc_holder(const ValAlloc &a)
+ : members_(a)
+ {}
+
+ node_alloc_holder(const node_alloc_holder &other)
+ : members_(other.node_alloc())
+ {}
+
+ node_alloc_holder(BOOST_RV_REF(node_alloc_holder) other)
+ : members_(boost::move(other.node_alloc()))
+ { this->swap(other); }
+
+ node_alloc_holder & operator=(BOOST_COPY_ASSIGN_REF(node_alloc_holder) other)
+ { members_.assign(other.node_alloc()); }
+
+ node_alloc_holder & operator=(BOOST_RV_REF(node_alloc_holder) other)
+ { members_.assign(other.node_alloc()); }
+
+ template<class Pred>
+ node_alloc_holder(const ValAlloc &a, const Pred &c)
+ : members_(a, typename ICont::value_compare(c))
+ {}
+
+ template<class Pred>
+ node_alloc_holder(BOOST_RV_REF(ValAlloc) a, const Pred &c)
+ : members_(a, typename ICont::value_compare(c))
+ {}
+
+ template<class Pred>
+ node_alloc_holder(const node_alloc_holder &other, const Pred &c)
+ : members_(other.node_alloc(), typename ICont::value_compare(c))
+ {}
+
+ ~node_alloc_holder()
+ { this->clear(alloc_version()); }
+
+ size_type max_size() const
+ { return this->node_alloc().max_size(); }
+
+ NodePtr allocate_one()
+ { return this->allocate_one(alloc_version()); }
+
+ NodePtr allocate_one(allocator_v1)
+ { return this->node_alloc().allocate(1); }
+
+ NodePtr allocate_one(allocator_v2)
+ { return this->node_alloc().allocate_one(); }
+
+ void deallocate_one(NodePtr p)
+ { return this->deallocate_one(p, alloc_version()); }
+
+ void deallocate_one(NodePtr p, allocator_v1)
+ { this->node_alloc().deallocate(p, 1); }
+
+ void deallocate_one(NodePtr p, allocator_v2)
+ { this->node_alloc().deallocate_one(p); }
+
+ template<class Convertible1, class Convertible2>
+ static void construct(const NodePtr &ptr,
+ 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 = containers_detail::get_pointer(ptr);
+
+ //Hook constructor does not throw
+ new(static_cast<hook_type*>(nodeptr))hook_type();
+ //Now construct pair members_holder
+ value_type *valueptr = &nodeptr->get_data();
+ new((void*)&valueptr->first) first_type(boost::move(value.first));
+ BOOST_TRY{
+ new((void*)&valueptr->second) second_type(boost::move(value.second));
+ }
+ BOOST_CATCH(...){
+ valueptr->first.~first_type();
+ static_cast<hook_type*>(nodeptr)->~hook_type();
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ static void destroy(const NodePtr &ptr)
+ { containers_detail::get_pointer(ptr)->~Node(); }
+
+ Deallocator create_node_and_deallocator()
+ {
+ return Deallocator(this->allocate_one(), this->node_alloc());
+ }
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ static void construct(const NodePtr &ptr, Args &&...args)
+ { new((void*)containers_detail::get_pointer(ptr)) Node(boost::forward<Args>(args)...); }
+
+ template<class ...Args>
+ NodePtr create_node(Args &&...args)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ self_t::construct(p, boost::forward<Args>(args)...);
+ node_deallocator.release();
+ return (p);
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ static void construct(const NodePtr &ptr)
+ { new((void*)containers_detail::get_pointer(ptr)) Node(); }
+
+ NodePtr create_node()
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ self_t::construct(p);
+ node_deallocator.release();
+ return (p);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ new((void*)containers_detail::get_pointer(ptr)) \
+ Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p = this->allocate_one(); \
+ Deallocator node_deallocator(p, this->node_alloc()); \
+ self_t::construct(p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ node_deallocator.release(); \
+ return (p); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class It>
+ NodePtr create_node_from_it(It it)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ ::boost::container::construct_in_place(containers_detail::get_pointer(p), it);
+ node_deallocator.release();
+ return (p);
+ }
+
+ void destroy_node(NodePtr node)
+ {
+ self_t::destroy(node);
+ this->deallocate_one(node);
+ }
+
+ void swap(node_alloc_holder &x)
+ {
+ NodeAlloc& this_alloc = this->node_alloc();
+ NodeAlloc& other_alloc = x.node_alloc();
+
+ if (this_alloc != other_alloc){
+ containers_detail::do_swap(this_alloc, other_alloc);
+ }
+
+ this->icont().swap(x.icont());
+ }
+
+ template<class FwdIterator, class Inserter>
+ FwdIterator allocate_many_and_construct
+ (FwdIterator beg, difference_type n, Inserter inserter)
+ {
+ if(n){
+ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+
+ //Try to allocate memory in a single block
+ multiallocation_chain mem(this->node_alloc().allocate_individual(n));
+ int constructed = 0;
+ Node *p = 0;
+ BOOST_TRY{
+ for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
+ p = containers_detail::get_pointer(mem.front());
+ mem.pop_front();
+ //This can throw
+ constructed = 0;
+ boost::container::construct_in_place(p, beg);
+ ++constructed;
+ //This can throw in some containers (predicate might throw)
+ inserter(*p);
+ }
+ }
+ BOOST_CATCH(...){
+ if(constructed){
+ this->destroy(p);
+ }
+ this->node_alloc().deallocate_individual(boost::move(mem));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+ return beg;
+ }
+
+ void clear(allocator_v1)
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+
+ void clear(allocator_v2)
+ {
+ typename NodeAlloc::multiallocation_chain chain;
+ allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
+ this->icont().clear_and_dispose(builder);
+ //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
+ if(!chain.empty())
+ this->node_alloc().deallocate_individual(boost::move(chain));
+ }
+
+ icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
+ { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
+
+ icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
+ }
+
+ template<class Key, class Comparator>
+ size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
+ { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
+
+ template<class Key, class Comparator>
+ size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
+ }
+
+ protected:
+ struct cloner
+ {
+ cloner(node_alloc_holder &holder)
+ : m_holder(holder)
+ {}
+
+ NodePtr operator()(const Node &other) const
+ { return m_holder.create_node(other.get_data()); }
+
+ node_alloc_holder &m_holder;
+ };
+
+ struct destroyer
+ {
+ destroyer(node_alloc_holder &holder)
+ : m_holder(holder)
+ {}
+
+ void operator()(NodePtr n) const
+ { m_holder.destroy_node(n); }
+
+ node_alloc_holder &m_holder;
+ };
+
+ struct members_holder
+ : public NodeAlloc
+ {
+ private:
+ members_holder(const members_holder&);
+
+ public:
+ template<class ConvertibleToAlloc>
+ members_holder(const ConvertibleToAlloc &c2alloc)
+ : NodeAlloc(c2alloc)
+ {}
+
+ template<class ConvertibleToAlloc, class Pred>
+ members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
+ : NodeAlloc(c2alloc), m_icont(c)
+ {}
+
+ template<class ConvertibleToAlloc>
+ void assign (const ConvertibleToAlloc &c2alloc)
+ {
+ NodeAlloc::operator=(c2alloc);
+ }
+
+ //The intrusive container
+ ICont m_icont;
+ } members_;
+
+ ICont &non_const_icont() const
+ { return const_cast<ICont&>(this->members_.m_icont); }
+
+ ICont &icont()
+ { return this->members_.m_icont; }
+
+ const ICont &icont() const
+ { return this->members_.m_icont; }
+
+ NodeAlloc &node_alloc()
+ { return static_cast<NodeAlloc &>(this->members_); }
+
+ const NodeAlloc &node_alloc() const
+ { return static_cast<const NodeAlloc &>(this->members_); }
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
Added: branches/release/boost/container/detail/node_pool_impl.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/node_pool_impl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,367 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/math_functions.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/pool_common.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+#include <functional> //std::unary_function
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class SegmentManagerBase>
+class private_node_pool_impl
+{
+ //Non-copyable
+ private_node_pool_impl();
+ private_node_pool_impl(const private_node_pool_impl &);
+ private_node_pool_impl &operator=(const private_node_pool_impl &);
+
+ //A node object will hold node_t when it's not allocated
+ public:
+ typedef typename SegmentManagerBase::void_pointer void_pointer;
+ typedef typename node_slist<void_pointer>::slist_hook_t slist_hook_t;
+ typedef typename node_slist<void_pointer>::node_t node_t;
+ typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
+ typedef typename SegmentManagerBase::size_type size_type;
+
+ private:
+ typedef typename bi::make_slist
+ < node_t, bi::base_hook<slist_hook_t>
+ , bi::linear<true>
+ , bi::constant_time_size<false> >::type blockslist_t;
+ public:
+
+ //!Segment manager typedef
+ typedef SegmentManagerBase segment_manager_base_type;
+
+ //!Constructor from a segment manager. Never throws
+ private_node_pool_impl(segment_manager_base_type *segment_mngr_base, size_type node_size, size_type nodes_per_block)
+ : m_nodes_per_block(nodes_per_block)
+ , m_real_node_size(lcm(node_size, size_type(alignment_of<node_t>::value)))
+ //General purpose allocator
+ , mp_segment_mngr_base(segment_mngr_base)
+ , m_blocklist()
+ , m_freelist()
+ //Debug node count
+ , m_allocated(0)
+ {}
+
+ //!Destructor. Deallocates all allocated blocks. Never throws
+ ~private_node_pool_impl()
+ { this->purge_blocks(); }
+
+ size_type get_real_num_node() const
+ { return m_nodes_per_block; }
+
+ //!Returns the segment manager. Never throws
+ segment_manager_base_type* get_segment_manager_base()const
+ { return containers_detail::get_pointer(mp_segment_mngr_base); }
+
+ void *allocate_node()
+ { return priv_alloc_node(); }
+
+ //!Deallocates an array pointed by ptr. Never throws
+ void deallocate_node(void *ptr)
+ { priv_dealloc_node(ptr); }
+
+ //!Allocates a singly linked list of n nodes ending in null pointer.
+ multiallocation_chain allocate_nodes(const size_type n)
+ {
+ //Preallocate all needed blocks to fulfill the request
+ size_type cur_nodes = m_freelist.size();
+ if(cur_nodes < n){
+ priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
+ }
+
+ //We just iterate the needed nodes to get the last we'll erase
+ typedef typename free_nodes_t::iterator free_iterator;
+ free_iterator before_last_new_it = m_freelist.before_begin();
+ for(size_type j = 0; j != n; ++j){
+ ++before_last_new_it;
+ }
+
+ //Cache the first node of the allocated range before erasing
+ free_iterator first_node(m_freelist.begin());
+ free_iterator last_node (before_last_new_it);
+
+ //Erase the range. Since we already have the distance, this is O(1)
+ m_freelist.erase_after( m_freelist.before_begin()
+ , ++free_iterator(before_last_new_it)
+ , n);
+
+ //Now take the last erased node and just splice it in the end
+ //of the intrusive list that will be traversed by the multialloc iterator.
+ multiallocation_chain chain;
+ chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
+ m_allocated += n;
+ return boost::move(chain);
+ }
+
+ void deallocate_nodes(multiallocation_chain chain)
+ {
+ typedef typename multiallocation_chain::iterator iterator;
+ iterator it(chain.begin()), itend(chain.end());
+ while(it != itend){
+ void *pElem = &*it;
+ ++it;
+ priv_dealloc_node(pElem);
+ }
+ }
+
+ //!Deallocates all the free blocks of memory. Never throws
+ void deallocate_free_blocks()
+ {
+ typedef typename free_nodes_t::iterator nodelist_iterator;
+ typename blockslist_t::iterator bit(m_blocklist.before_begin()),
+ it(m_blocklist.begin()),
+ itend(m_blocklist.end());
+ free_nodes_t backup_list;
+ nodelist_iterator backup_list_last = backup_list.before_begin();
+
+ //Execute the algorithm and get an iterator to the last value
+ size_type blocksize = get_rounded_size
+ (m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value);
+
+ while(it != itend){
+ //Collect all the nodes from the block pointed by it
+ //and push them in the list
+ free_nodes_t free_nodes;
+ nodelist_iterator last_it = free_nodes.before_begin();
+ const void *addr = get_block_from_hook(&*it, blocksize);
+
+ m_freelist.remove_and_dispose_if
+ (is_between(addr, blocksize), push_in_list(free_nodes, last_it));
+
+ //If the number of nodes is equal to m_nodes_per_block
+ //this means that the block can be deallocated
+ if(free_nodes.size() == m_nodes_per_block){
+ //Unlink the nodes
+ free_nodes.clear();
+ it = m_blocklist.erase_after(bit);
+ mp_segment_mngr_base->deallocate((void*)addr);
+ }
+ //Otherwise, insert them in the backup list, since the
+ //next "remove_if" does not need to check them again.
+ else{
+ //Assign the iterator to the last value if necessary
+ if(backup_list.empty() && !m_freelist.empty()){
+ backup_list_last = last_it;
+ }
+ //Transfer nodes. This is constant time.
+ backup_list.splice_after
+ ( backup_list.before_begin()
+ , free_nodes
+ , free_nodes.before_begin()
+ , last_it
+ , free_nodes.size());
+ bit = it;
+ ++it;
+ }
+ }
+ //We should have removed all the nodes from the free list
+ BOOST_ASSERT(m_freelist.empty());
+
+ //Now pass all the node to the free list again
+ m_freelist.splice_after
+ ( m_freelist.before_begin()
+ , backup_list
+ , backup_list.before_begin()
+ , backup_list_last
+ , backup_list.size());
+ }
+
+ size_type num_free_nodes()
+ { return m_freelist.size(); }
+
+ //!Deallocates all used memory. Precondition: all nodes allocated from this pool should
+ //!already be deallocated. Otherwise, undefined behaviour. Never throws
+ void purge_blocks()
+ {
+ //check for memory leaks
+ BOOST_ASSERT(m_allocated==0);
+ size_type blocksize = get_rounded_size
+ (m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
+ typename blockslist_t::iterator
+ it(m_blocklist.begin()), itend(m_blocklist.end()), aux;
+
+ //We iterate though the NodeBlock list to free the memory
+ while(!m_blocklist.empty()){
+ void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
+ m_blocklist.pop_front();
+ mp_segment_mngr_base->deallocate((void*)addr);
+ }
+ //Just clear free node list
+ m_freelist.clear();
+ }
+
+ void swap(private_node_pool_impl &other)
+ {
+ BOOST_ASSERT(m_nodes_per_block == other.m_nodes_per_block);
+ BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
+ std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+ m_blocklist.swap(other.m_blocklist);
+ m_freelist.swap(other.m_freelist);
+ std::swap(m_allocated, other.m_allocated);
+ }
+
+ private:
+
+ struct push_in_list
+ {
+ push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
+ : slist_(l), last_it_(it)
+ {}
+
+ void operator()(typename free_nodes_t::pointer p) const
+ {
+ slist_.push_front(*p);
+ if(slist_.size() == 1){ //Cache last element
+ ++last_it_ = slist_.begin();
+ }
+ }
+
+ private:
+ free_nodes_t &slist_;
+ typename free_nodes_t::iterator &last_it_;
+ };
+
+ struct is_between
+ : std::unary_function<typename free_nodes_t::value_type, bool>
+ {
+ is_between(const void *addr, std::size_t size)
+ : beg_(static_cast<const char *>(addr)), end_(beg_+size)
+ {}
+
+ bool operator()(typename free_nodes_t::const_reference v) const
+ {
+ return (beg_ <= reinterpret_cast<const char *>(&v) &&
+ end_ > reinterpret_cast<const char *>(&v));
+ }
+ private:
+ const char * beg_;
+ const char * end_;
+ };
+
+ //!Allocates one node, using single segregated storage algorithm.
+ //!Never throws
+ node_t *priv_alloc_node()
+ {
+ //If there are no free nodes we allocate a new block
+ if (m_freelist.empty())
+ priv_alloc_block();
+ //We take the first free node
+ node_t *n = (node_t*)&m_freelist.front();
+ m_freelist.pop_front();
+ ++m_allocated;
+ return n;
+ }
+
+ //!Deallocates one node, using single segregated storage algorithm.
+ //!Never throws
+ void priv_dealloc_node(void *pElem)
+ {
+ //We put the node at the beginning of the free node list
+ node_t * to_deallocate = static_cast<node_t*>(pElem);
+ m_freelist.push_front(*to_deallocate);
+ BOOST_ASSERT(m_allocated>0);
+ --m_allocated;
+ }
+
+ //!Allocates several blocks of nodes. Can throw
+ void priv_alloc_block(size_type num_blocks = 1)
+ {
+ if(!num_blocks)
+ return;
+ size_type blocksize =
+ get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
+
+ try{
+ for(size_type i = 0; i != num_blocks; ++i){
+ //We allocate a new NodeBlock and put it as first
+ //element in the free Node list
+ char *pNode = reinterpret_cast<char*>
+ (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
+ char *pBlock = pNode;
+ m_blocklist.push_front(get_block_hook(pBlock, blocksize));
+
+ //We initialize all Nodes in Node Block to insert
+ //them in the free Node list
+ for(size_type i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
+ m_freelist.push_front(*new (pNode) node_t);
+ }
+ }
+ }
+ catch(...){
+ //to-do: if possible, an efficient way to deallocate allocated blocks
+ throw;
+ }
+ }
+
+ //!Deprecated, use deallocate_free_blocks
+ void deallocate_free_chunks()
+ { this->deallocate_free_blocks(); }
+
+ //!Deprecated, use purge_blocks
+ void purge_chunks()
+ { this->purge_blocks(); }
+
+ private:
+ //!Returns a reference to the block hook placed in the end of the block
+ static node_t & get_block_hook (void *block, size_type blocksize)
+ {
+ return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
+ }
+
+ //!Returns the starting address of the block reference to the block hook placed in the end of the block
+ void *get_block_from_hook (node_t *hook, size_type blocksize)
+ {
+ return (reinterpret_cast<char*>(hook) - blocksize);
+ }
+
+ private:
+ typedef typename boost::pointer_to_other
+ <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
+
+ const size_type m_nodes_per_block;
+ const size_type m_real_node_size;
+ segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
+ blockslist_t m_blocklist; //Intrusive container of blocks
+ free_nodes_t m_freelist; //Intrusive container of free nods
+ size_type m_allocated; //Used nodes for debugging
+};
+
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
Added: branches/release/boost/container/detail/pair.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/pair.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,320 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
+#define BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <utility> //std::pair
+
+#include <boost/move/move.hpp>
+#include <boost/type_traits/is_class.hpp>
+
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template <class T1, class T2>
+struct pair;
+
+template <class T>
+struct is_pair
+{
+ static const bool value = false;
+};
+
+template <class T1, class T2>
+struct is_pair< pair<T1, T2> >
+{
+ static const bool value = true;
+};
+
+template <class T1, class T2>
+struct is_pair< std::pair<T1, T2> >
+{
+ static const bool value = true;
+};
+
+struct pair_nat;
+
+struct piecewise_construct_t { };
+static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
+
+template <class T1, class T2>
+struct pair
+{
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(pair)
+
+ public:
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ T1 first;
+ T2 second;
+
+ //Default constructor
+ 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)
+ {}
+
+ 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)
+ : 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))
+ {}
+
+ //std::pair copy constructor
+ pair(const std::pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
+ template <class D, class S>
+ pair(const std::pair<D, S>& p)
+ : 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)
+ : first(::boost::move(p.first)), second(::boost::move(p.second))
+ {}
+
+ pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ : first(::boost::move(p.first)), second(::boost::move(p.second))
+ {}
+
+ //piecewise_construct missing
+/*
+ //Variadic versions
+ template<class U>
+ pair(BOOST_CONTAINERS_PARAM(U, u), typename containers_detail::disable_if
+ < containers_detail::is_pair< typename containers_detail::remove_ref_const<U>::type >, pair_nat>::type* = 0)
+ : first(::boost::forward<U>(u))
+ , second()
+ {}
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template<class U, class V, class ...Args>
+ pair(U &&u, V &&v)
+ : first(::boost::forward<U>(u))
+ , second(::boost::forward<V>(v), ::boost::forward<Args>(args)...)
+ {}
+
+ #else
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
+ pair(BOOST_CONTAINERS_PARAM(U, u) \
+ ,BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : first(::boost::forward<U>(u)) \
+ , second(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+ #endif
+*/
+ //pair copy assignment
+ pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
+ {
+ first = p.first;
+ second = p.second;
+ 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)
+ {
+ first = ::boost::move(p.first);
+ second = ::boost::move(p.second);
+ return *this;
+ }
+
+ template <class D, class S>
+ pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+ {
+ first = ::boost::move(p.first);
+ second = ::boost::move(p.second);
+ return *this;
+ }
+
+ //std::pair copy assignment
+ pair& operator=(const std::pair<T1, T2> &p)
+ {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+
+ template <class D, class S>
+ pair& operator=(const std::pair<D, S> &p)
+ {
+ first = ::boost::move(p.first);
+ second = ::boost::move(p.second);
+ return *this;
+ }
+
+ //std::pair move assignment
+ pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+ {
+ first = ::boost::move(p.first);
+ second = ::boost::move(p.second);
+ return *this;
+ }
+
+ template <class D, class S>
+ pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+ {
+ first = ::boost::move(p.first);
+ second = ::boost::move(p.second);
+ return *this;
+ }
+
+ //swap
+ void swap(pair& p)
+ {
+ using std::swap;
+ swap(this->first, p.first);
+ swap(this->second, p.second);
+ }
+};
+
+template <class T1, class T2>
+inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(x.first == y.first && x.second == y.second); }
+
+template <class T1, class T2>
+inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(x.first < y.first ||
+ (!(y.first < x.first) && x.second < y.second)); }
+
+template <class T1, class T2>
+inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(!(x == y)); }
+
+template <class T1, class T2>
+inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return y < x; }
+
+template <class T1, class T2>
+inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(!(x < y)); }
+
+template <class T1, class T2>
+inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
+{ return static_cast<bool>(!(y < x)); }
+
+template <class T1, class T2>
+inline pair<T1, T2> make_pair(T1 x, T2 y)
+{ return pair<T1, T2>(x, y); }
+
+template <class T1, class T2>
+inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
+{
+ swap(x.first, y.first);
+ swap(x.second, y.second);
+}
+
+} //namespace containers_detail {
+} //namespace container {
+
+
+//Without this specialization recursive flat_(multi)map instantiation fails
+//because is_enum needs to instantiate the recursive pair, leading to a compilation error).
+//This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
+template<class T>
+struct is_enum;
+
+template<class T, class U>
+struct is_enum< ::boost::container::containers_detail::pair<T, U> >
+{
+ static const bool value = false;
+};
+
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+template <class T1, class T2>
+struct is_class< ::boost::container::containers_detail::pair<T1, T2> >
+ : public ::boost::true_type
+{};
+
+#ifdef BOOST_NO_RVALUE_REFERENCES
+
+template<class T1, class T2>
+struct has_move_emulation_enabled< ::boost::container::containers_detail::pair<T1, T2> >
+ : ::boost::true_type
+{};
+
+#endif
+
+
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_PAIR_HPP
Added: branches/release/boost/container/detail/pool_common.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/pool_common.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,52 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/intrusive/slist.hpp>
+#include <new>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class VoidPointer>
+struct node_slist
+{
+ //This hook will be used to chain the individual nodes
+ typedef typename bi::make_slist_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type slist_hook_t;
+
+ //A node object will hold node_t when it's not allocated
+ typedef slist_hook_t node_t;
+
+ typedef typename bi::make_slist
+ <node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
+};
+
+template<class T>
+struct is_stateless_segment_manager
+{
+ static const bool value = false;
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
Added: branches/release/boost/container/detail/preprocessor.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/preprocessor.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,141 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
+#define BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+#include <boost/container/detail/stored_ref.hpp>
+#endif
+
+#include <boost/container/detail/workaround.hpp>
+
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+#error "This file is not needed when perfect forwarding is available"
+#endif
+
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+
+#define BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS 10
+
+//Note:
+//We define template parameters as const references to
+//be able to bind temporaries. After that we will un-const them.
+//This cast is ugly but it is necessary until "perfect forwarding"
+//is achieved in C++0x. Meanwhile, if we want to be able to
+//bind rvalues with non-const references, we have to be ugly
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ #define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
+ BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
+ //!
+#else
+ #define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
+ const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
+ //!
+#endif
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+ #define BOOST_CONTAINERS_PARAM(U, u) \
+ U && u \
+ //!
+#else
+ #define BOOST_CONTAINERS_PARAM(U, u) \
+ const U & u \
+ //!
+#endif
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+#define BOOST_CONTAINERS_AUX_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_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
+//!
+
+#endif
+
+#else
+#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
+//!
+#endif
+
+#define BOOST_CONTAINERS_AUX_PARAM_INC(z, n, data) \
+ BOOST_PP_CAT(++m_p, n) \
+//!
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
+ BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
+//!
+
+#else
+
+#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
+ BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
+//!
+
+#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+
+#else
+#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
+ BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
+//!
+#endif
+
+#define BOOST_CONTAINERS_PP_PARAM_FORWARD(z, n, data) \
+boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+//!
+
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
+::boost::container::containers_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
+//!
+
+#else
+
+#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
+boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
+//!
+
+#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#define BOOST_CONTAINERS_PP_MEMBER_IT_FORWARD(z, n, data) \
+BOOST_PP_CAT(*m_p, n) \
+//!
+
+#include <boost/container/detail/config_end.hpp>
+
+#else
+#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+#error "This file is not needed when perfect forwarding is available"
+#endif
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
Added: branches/release/boost/container/detail/stored_ref.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/stored_ref.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
+#define BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+namespace boost{
+namespace container{
+namespace containers_detail{
+
+template<class T>
+struct stored_ref
+{
+
+ static T && forward(T &t)
+ #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ { return t; }
+ #else
+ { return boost::move(t); }
+ #endif
+};
+
+template<class T>
+struct stored_ref<const T>
+{
+ static const T && forward(const T &t)
+ #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ { return t; }
+ #else
+ { return static_cast<const T&&>(t); }
+ #endif
+};
+
+template<class T>
+struct stored_ref<T&&>
+{
+ static T && forward(T &t)
+ #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ { return t; }
+ #else
+ { return boost::move(t); }
+ #endif
+};
+
+template<class T>
+struct stored_ref<const T&&>
+{
+ static const T && forward(const T &t)
+ #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ { return t; }
+ #else
+ { return static_cast<const T &&>(t); }
+ #endif
+};
+
+template<class T>
+struct stored_ref<const T&>
+{
+ static const T & forward(const T &t)
+ { return t; }
+};
+
+template<class T>
+struct stored_ref<T&>
+{
+ static T & forward(T &t)
+ { return t; }
+};
+
+} //namespace containers_detail{
+} //namespace container{
+} //namespace boost{
+
+#else
+#error "This header can be included only for compiler with rvalue references"
+#endif //BOOST_NO_RVALUE_REFERENCES
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
Added: branches/release/boost/container/detail/transform_iterator.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/transform_iterator.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,176 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
+#define BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <iterator>
+
+namespace boost {
+namespace container {
+
+template <class PseudoReference>
+struct operator_arrow_proxy
+{
+ operator_arrow_proxy(const PseudoReference &px)
+ : m_value(px)
+ {}
+
+ PseudoReference* operator->() const { return &m_value; }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+// operator T*() const { return &m_value; }
+ mutable PseudoReference m_value;
+};
+
+template <class T>
+struct operator_arrow_proxy<T&>
+{
+ operator_arrow_proxy(T &px)
+ : m_value(px)
+ {}
+
+ T* operator->() const { return const_cast<T*>(&m_value); }
+ // This function is needed for MWCW and BCC, which won't call operator->
+ // again automatically per 13.3.1.2 para 8
+// operator T*() const { return &m_value; }
+ T &m_value;
+};
+
+template <class Iterator, class UnaryFunction>
+class transform_iterator
+ : public UnaryFunction
+ , public std::iterator
+ < typename Iterator::iterator_category
+ , typename containers_detail::remove_reference<typename UnaryFunction::result_type>::type
+ , typename Iterator::difference_type
+ , operator_arrow_proxy<typename UnaryFunction::result_type>
+ , typename UnaryFunction::result_type>
+{
+ public:
+ explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
+ : UnaryFunction(f), m_it(it)
+ {}
+
+ explicit transform_iterator()
+ : UnaryFunction(), m_it()
+ {}
+
+ //Constructors
+ transform_iterator& operator++()
+ { increment(); return *this; }
+
+ transform_iterator operator++(int)
+ {
+ transform_iterator result (*this);
+ increment();
+ return result;
+ }
+
+ friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
+ { return i.equal(i2); }
+
+ friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i == i2); }
+
+/*
+ friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
+ { return i2 < i; }
+
+ friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i > i2); }
+
+ friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
+ { return !(i < i2); }
+*/
+ friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
+ { return i2.distance_to(i); }
+
+ //Arithmetic
+ transform_iterator& operator+=(typename Iterator::difference_type off)
+ { this->advance(off); return *this; }
+
+ transform_iterator operator+(typename Iterator::difference_type off) const
+ {
+ transform_iterator other(*this);
+ other.advance(off);
+ return other;
+ }
+
+ friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
+ { return right + off; }
+
+ transform_iterator& operator-=(typename Iterator::difference_type off)
+ { this->advance(-off); return *this; }
+
+ transform_iterator operator-(typename Iterator::difference_type off) const
+ { return *this + (-off); }
+
+ typename UnaryFunction::result_type operator*() const
+ { return dereference(); }
+
+ operator_arrow_proxy<typename UnaryFunction::result_type>
+ operator->() const
+ { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
+
+ Iterator & base()
+ { return m_it; }
+
+ const Iterator & base() const
+ { return m_it; }
+
+ private:
+ Iterator m_it;
+
+ void increment()
+ { ++m_it; }
+
+ void decrement()
+ { --m_it; }
+
+ bool equal(const transform_iterator &other) const
+ { return m_it == other.m_it; }
+
+ bool less(const transform_iterator &other) const
+ { return other.m_it < m_it; }
+
+ typename UnaryFunction::result_type dereference() const
+ { return UnaryFunction::operator()(*m_it); }
+
+ void advance(typename Iterator::difference_type n)
+ { std::advance(m_it, n); }
+
+ typename Iterator::difference_type distance_to(const transform_iterator &other)const
+ { return std::distance(other.m_it, m_it); }
+};
+
+template <class Iterator, class UnaryFunc>
+transform_iterator<Iterator, UnaryFunc>
+make_transform_iterator(Iterator it, UnaryFunc fun)
+{
+ return transform_iterator<Iterator, UnaryFunc>(it, fun);
+}
+
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
Added: branches/release/boost/container/detail/tree.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/tree.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1064 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_TREE_HPP
+#define BOOST_CONTAINERS_TREE_HPP
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+
+#include <boost/move/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/intrusive/rbtree.hpp>
+
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/algorithms.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+#include <utility> //std::pair
+#include <iterator>
+#include <algorithm>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class Key, class Value, class KeyCompare, class KeyOfValue>
+struct value_compare_impl
+ : public KeyCompare
+{
+ typedef Value value_type;
+ typedef KeyCompare key_compare;
+ typedef KeyOfValue key_of_value;
+ typedef Key key_type;
+
+ value_compare_impl(const key_compare &kcomp)
+ : key_compare(kcomp)
+ {}
+
+ const key_compare &key_comp() const
+ { return static_cast<const key_compare &>(*this); }
+
+ key_compare &key_comp()
+ { return static_cast<key_compare &>(*this); }
+
+ template<class T>
+ struct is_key
+ {
+ static const bool value = is_same<const T, const key_type>::value;
+ };
+
+ template<class T>
+ typename enable_if_c<is_key<T>::value, const key_type &>::type
+ key_forward(const T &key) const
+ { return key; }
+
+ template<class T>
+ typename enable_if_c<!is_key<T>::value, const key_type &>::type
+ key_forward(const T &key) const
+ { return KeyOfValue()(key); }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2) const
+ { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+};
+
+template<class VoidPointer>
+struct rbtree_hook
+{
+ typedef typename containers_detail::bi::make_set_base_hook
+ < containers_detail::bi::void_pointer<VoidPointer>
+ , containers_detail::bi::link_mode<containers_detail::bi::normal_link>
+ , containers_detail::bi::optimize_size<true>
+ >::type type;
+};
+
+template<class T>
+struct rbtree_type
+{
+ typedef T type;
+};
+
+template<class T1, class T2>
+struct rbtree_type< std::pair<T1, T2> >
+{
+ typedef pair<T1, T2> type;
+};
+
+template <class T, class VoidPointer>
+struct rbtree_node
+ : public rbtree_hook<VoidPointer>::type
+{
+ typedef typename rbtree_hook<VoidPointer>::type hook_type;
+
+ typedef T value_type;
+ typedef typename rbtree_type<T>::type internal_type;
+
+ typedef rbtree_node<T, VoidPointer> node_type;
+
+ #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ rbtree_node()
+ : m_data()
+ {}
+
+ rbtree_node(const rbtree_node &other)
+ : m_data(other.m_data)
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ rbtree_node()
+ : m_data()
+ {}
+
+ template<class ...Args>
+ rbtree_node(Args &&...args)
+ : m_data(boost::forward<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ rbtree_node &operator=(const rbtree_node &other)
+ { do_assign(other.m_data); return *this; }
+
+ T &get_data()
+ {
+ T* ptr = reinterpret_cast<T*>(&this->m_data);
+ return *ptr;
+ }
+
+ const T &get_data() const
+ {
+ const T* ptr = reinterpret_cast<const T*>(&this->m_data);
+ return *ptr;
+ }
+
+ private:
+ internal_type m_data;
+
+ template<class A, class B>
+ void do_assign(const std::pair<const A, B> &p)
+ {
+ const_cast<A&>(m_data.first) = p.first;
+ m_data.second = p.second;
+ }
+
+ template<class A, class B>
+ void do_assign(const pair<const A, B> &p)
+ {
+ const_cast<A&>(m_data.first) = p.first;
+ m_data.second = p.second;
+ }
+
+ template<class V>
+ void do_assign(const V &v)
+ { m_data = v; }
+
+ public:
+ template<class Convertible>
+ static void construct(node_type *ptr, BOOST_FWD_REF(Convertible) convertible)
+ { new(ptr) node_type(boost::forward<Convertible>(convertible)); }
+};
+
+}//namespace containers_detail {
+#if defined(BOOST_NO_RVALUE_REFERENCES)
+template<class T, class VoidPointer>
+struct has_own_construct_from_it
+ < boost::container::containers_detail::rbtree_node<T, VoidPointer> >
+{
+ static const bool value = true;
+};
+#endif
+namespace containers_detail {
+
+template<class A, class ValueCompare>
+struct intrusive_rbtree_type
+{
+ typedef typename A::value_type value_type;
+ typedef typename boost::pointer_to_other
+ <typename A::pointer, void>::type void_pointer;
+ typedef typename containers_detail::rbtree_node
+ <value_type, void_pointer> node_type;
+ typedef node_compare<ValueCompare, node_type> node_compare_type;
+ typedef typename containers_detail::bi::make_rbtree
+ <node_type
+ ,containers_detail::bi::compare<node_compare_type>
+ ,containers_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
+ ,containers_detail::bi::constant_time_size<true>
+ ,containers_detail::bi::size_type<typename A::size_type>
+ >::type container_type;
+ typedef container_type type ;
+};
+
+} //namespace containers_detail {
+
+namespace containers_detail {
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+class rbtree
+ : protected containers_detail::node_alloc_holder
+ <A, typename containers_detail::intrusive_rbtree_type
+ <A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue>
+ >::type
+ >
+{
+ typedef typename containers_detail::intrusive_rbtree_type
+ <A, value_compare_impl
+ <Key, Value, KeyCompare, KeyOfValue>
+ >::type Icont;
+ typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef rbtree < Key, Value, KeyOfValue
+ , KeyCompare, A> ThisType;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef typename Icont::iterator iiterator;
+ typedef typename Icont::const_iterator iconst_iterator;
+ typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::allocator_v1 allocator_v1;
+ typedef typename AllocHolder::allocator_v2 allocator_v2;
+ typedef typename AllocHolder::alloc_version alloc_version;
+
+ class RecyclingCloner;
+ friend class RecyclingCloner;
+
+ class RecyclingCloner
+ {
+ public:
+ RecyclingCloner(AllocHolder &holder, Icont &irbtree)
+ : m_holder(holder), m_icont(irbtree)
+ {}
+
+ NodePtr operator()(const Node &other) const
+ {
+// if(!m_icont.empty()){
+ if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
+ //First recycle a node (this can't throw)
+ //NodePtr p = m_icont.unlink_leftmost_without_rebalance();
+ try{
+ //This can throw
+ *p = other;
+ return p;
+ }
+ catch(...){
+ //If there is an exception destroy the whole source
+ m_holder.destroy_node(p);
+ while((p = m_icont.unlink_leftmost_without_rebalance())){
+ m_holder.destroy_node(p);
+ }
+ throw;
+ }
+ }
+ else{
+ return m_holder.create_node(other);
+ }
+ }
+
+ AllocHolder &m_holder;
+ Icont &m_icont;
+ };
+ BOOST_COPYABLE_AND_MOVABLE(rbtree)
+
+ public:
+
+ typedef Key key_type;
+ typedef Value value_type;
+ typedef A allocator_type;
+ typedef KeyCompare key_compare;
+ typedef value_compare_impl< Key, Value
+ , KeyCompare, KeyOfValue> value_compare;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef typename A::size_type size_type;
+ typedef typename A::difference_type difference_type;
+ typedef difference_type rbtree_difference_type;
+ typedef pointer rbtree_pointer;
+ typedef const_pointer rbtree_const_pointer;
+ typedef reference rbtree_reference;
+ typedef const_reference rbtree_const_reference;
+ typedef NodeAlloc stored_allocator_type;
+
+ private:
+
+ template<class KeyValueCompare>
+ struct key_node_compare
+ : private KeyValueCompare
+ {
+ key_node_compare(const KeyValueCompare &comp)
+ : KeyValueCompare(comp)
+ {}
+
+ template<class T>
+ struct is_node
+ {
+ static const bool value = is_same<T, Node>::value;
+ };
+
+ template<class T>
+ typename enable_if_c<is_node<T>::value, const value_type &>::type
+ key_forward(const T &node) const
+ { return node.get_data(); }
+
+ template<class T>
+ typename enable_if_c<!is_node<T>::value, const T &>::type
+ key_forward(const T &key) const
+ { return key; }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2) const
+ { return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+ };
+
+ typedef key_node_compare<value_compare> KeyNodeCompare;
+
+ public:
+ //rbtree const_iterator
+ class const_iterator
+ : public std::iterator
+ < std::bidirectional_iterator_tag
+ , value_type , rbtree_difference_type
+ , rbtree_const_pointer , rbtree_const_reference>
+ {
+ protected:
+ typedef typename Icont::iterator iiterator;
+ iiterator m_it;
+ explicit const_iterator(iiterator it) : m_it(it){}
+ void prot_incr() { ++m_it; }
+ void prot_decr() { --m_it; }
+
+ private:
+ iiterator get()
+ { return this->m_it; }
+
+ public:
+ friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
+ typedef rbtree_difference_type difference_type;
+
+ //Constructors
+ const_iterator()
+ : m_it()
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return m_it->get_data(); }
+
+ const_pointer operator->() const
+ { return const_pointer(&m_it->get_data()); }
+
+ //Increment / Decrement
+ const_iterator& operator++()
+ { prot_incr(); return *this; }
+
+ const_iterator operator++(int)
+ { iiterator tmp = m_it; ++*this; return const_iterator(tmp); }
+
+ const_iterator& operator--()
+ { prot_decr(); return *this; }
+
+ const_iterator operator--(int)
+ { iiterator tmp = m_it; --*this; return const_iterator(tmp); }
+
+ //Comparison operators
+ bool operator== (const const_iterator& r) const
+ { return m_it == r.m_it; }
+
+ bool operator!= (const const_iterator& r) const
+ { return m_it != r.m_it; }
+ };
+
+ //rbtree iterator
+ class iterator : public const_iterator
+ {
+ private:
+ explicit iterator(iiterator it)
+ : const_iterator(it)
+ {}
+
+ iiterator get()
+ { return this->m_it; }
+
+ public:
+ friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
+ typedef rbtree_pointer pointer;
+ typedef rbtree_reference reference;
+
+ //Constructors
+ iterator(){}
+
+ //Pointer like operators
+ reference operator*() const { return this->m_it->get_data(); }
+ pointer operator->() const { return pointer(&this->m_it->get_data()); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->prot_incr(); return *this; }
+
+ iterator operator++(int)
+ { iiterator tmp = this->m_it; ++*this; return iterator(tmp); }
+
+ iterator& operator--()
+ { this->prot_decr(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp = *this; --*this; return tmp; }
+ };
+
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ rbtree(const key_compare& comp = key_compare(),
+ const allocator_type& a = allocator_type())
+ : AllocHolder(a, comp)
+ {}
+
+ template <class InputIterator>
+ rbtree(InputIterator first, InputIterator last, const key_compare& comp,
+ const allocator_type& a, bool unique_insertion)
+ : AllocHolder(a, comp)
+ {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
+ }
+
+ template <class InputIterator>
+ rbtree( ordered_range_t, InputIterator first, InputIterator last
+ , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type())
+ : AllocHolder(a, comp)
+ {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
+ priv_create_and_insert_ordered_nodes(first, last, alloc_version(), ItCat());
+ }
+
+ rbtree(const rbtree& x)
+ : AllocHolder(x, x.key_comp())
+ {
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ }
+
+ rbtree(BOOST_RV_REF(rbtree) x)
+ : AllocHolder(x, x.key_comp())
+ { this->swap(x); }
+
+ ~rbtree()
+ {} //AllocHolder clears the tree
+
+ rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
+ {
+ if (this != &x) {
+ //Transfer all the nodes to a temporary tree
+ //If anything goes wrong, all the nodes will be destroyed
+ //automatically
+ Icont other_tree(this->icont().value_comp());
+ other_tree.swap(this->icont());
+
+ //Now recreate the source tree reusing nodes stored by other_tree
+ this->icont().clone_from
+ (x.icont()
+ , RecyclingCloner(*this, other_tree)
+ //, AllocHolder::cloner(*this)
+ , Destroyer(this->node_alloc()));
+
+ //If there are remaining nodes, destroy them
+ NodePtr p;
+ while((p = other_tree.unlink_leftmost_without_rebalance())){
+ AllocHolder::destroy_node(p);
+ }
+ }
+ return *this;
+ }
+
+ rbtree& operator=(BOOST_RV_REF(rbtree) mx)
+ { this->clear(); this->swap(mx); return *this; }
+
+ public:
+ // accessors:
+ value_compare value_comp() const
+ { return this->icont().value_comp().value_comp(); }
+
+ key_compare key_comp() const
+ { return this->icont().value_comp().value_comp().key_comp(); }
+
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ iterator begin()
+ { return iterator(this->icont().begin()); }
+
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ iterator end()
+ { return iterator(this->icont().end()); }
+
+ const_iterator end() const
+ { return this->cend(); }
+
+ reverse_iterator rbegin()
+ { return reverse_iterator(end()); }
+
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ reverse_iterator rend()
+ { return reverse_iterator(begin()); }
+
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(cend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(cbegin()); }
+
+ bool empty() const
+ { return !this->size(); }
+
+ size_type size() const
+ { return this->icont().size(); }
+
+ size_type max_size() const
+ { return AllocHolder::max_size(); }
+
+ void swap(ThisType& x)
+ { AllocHolder::swap(x); }
+
+ public:
+
+ typedef typename Icont::insert_commit_data insert_commit_data;
+
+ // insert/erase
+ std::pair<iterator,bool> insert_unique_check
+ (const key_type& key, insert_commit_data &data)
+ {
+ std::pair<iiterator, bool> ret =
+ this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
+ return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+ }
+
+ std::pair<iterator,bool> insert_unique_check
+ (const_iterator hint, const key_type& key, insert_commit_data &data)
+ {
+ std::pair<iiterator, bool> ret =
+ this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
+ return std::pair<iterator, bool>(iterator(ret.first), ret.second);
+ }
+
+ iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
+ {
+ NodePtr tmp = AllocHolder::create_node(v);
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
+ return iterator(it);
+ }
+
+ template<class MovableConvertible>
+ iterator insert_unique_commit
+ (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
+ {
+ NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
+ return iterator(it);
+ }
+
+ std::pair<iterator,bool> insert_unique(const value_type& v)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(v), data);
+ if(!ret.second)
+ return ret;
+ return std::pair<iterator,bool>
+ (this->insert_unique_commit(v, data), true);
+ }
+
+ template<class MovableConvertible>
+ std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) mv)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(mv), data);
+ if(!ret.second)
+ return ret;
+ return std::pair<iterator,bool>
+ (this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data), true);
+ }
+
+ private:
+ iterator emplace_unique_impl(NodePtr p)
+ {
+ value_type &v = p->get_data();
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(v), data);
+ if(!ret.second){
+ Destroyer(this->node_alloc())(p);
+ return ret.first;
+ }
+ return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+ }
+
+ iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
+ {
+ value_type &v = p->get_data();
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(v), data);
+ if(!ret.second){
+ Destroyer(this->node_alloc())(p);
+ return ret.first;
+ }
+ return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+ }
+
+ public:
+
+ #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ template <class... Args>
+ iterator emplace_unique(Args&&... args)
+ { return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
+
+ template <class... Args>
+ iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); }
+
+ template <class... Args>
+ iterator emplace_equal(Args&&... args)
+ {
+ NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ template <class... Args>
+ iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ {
+ NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace_unique()
+ { return this->emplace_unique_impl(AllocHolder::create_node()); }
+
+ iterator emplace_hint_unique(const_iterator hint)
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node()); }
+
+ iterator emplace_equal()
+ {
+ NodePtr p(AllocHolder::create_node());
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ iterator emplace_hint_equal(const_iterator hint)
+ {
+ NodePtr p(AllocHolder::create_node());
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_unique_impl \
+ (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_unique(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_unique_hint_impl \
+ (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_equal(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_equal(hint.get(), *p)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator insert_unique(const_iterator hint, const value_type& v)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(v), data);
+ if(!ret.second)
+ return ret.first;
+ return this->insert_unique_commit(v, data);
+ }
+
+ template<class MovableConvertible>
+ iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
+ {
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(mv), data);
+ if(!ret.second)
+ return ret.first;
+ return this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
+ }
+
+ template <class InputIterator>
+ void insert_unique(InputIterator first, InputIterator last)
+ {
+ if(this->empty()){
+ //Insert with end hint, to achieve linear
+ //complexity if [first, last) is ordered
+ const_iterator end(this->end());
+ for( ; first != last; ++first)
+ this->insert_unique(end, *first);
+ }
+ else{
+ for( ; first != last; ++first)
+ this->insert_unique(*first);
+ }
+ }
+
+ iterator insert_equal(const value_type& v)
+ {
+ NodePtr p(AllocHolder::create_node(v));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ template<class MovableConvertible>
+ iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
+ {
+ NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ iterator insert_equal(const_iterator hint, const value_type& v)
+ {
+ NodePtr p(AllocHolder::create_node(v));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ template<class MovableConvertible>
+ iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
+ {
+ NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ template <class InputIterator>
+ void insert_equal(InputIterator first, InputIterator last)
+ {
+ //Insert with end hint, to achieve linear
+ //complexity if [first, last) is ordered
+ const_iterator end(this->cend());
+ for( ; first != last; ++first)
+ this->insert_equal(end, *first);
+ }
+
+ iterator erase(const_iterator position)
+ { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
+
+ size_type erase(const key_type& k)
+ { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
+
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
+
+ void clear()
+ { AllocHolder::clear(alloc_version()); }
+
+ // set operations:
+ iterator find(const key_type& k)
+ { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
+
+ const_iterator find(const key_type& k) const
+ { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
+
+ size_type count(const key_type& k) const
+ { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
+
+ iterator lower_bound(const key_type& k)
+ { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
+
+ const_iterator lower_bound(const key_type& k) const
+ { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
+
+ iterator upper_bound(const key_type& k)
+ { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
+
+ const_iterator upper_bound(const key_type& k) const
+ { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
+
+ std::pair<iterator,iterator> equal_range(const key_type& k)
+ {
+ std::pair<iiterator, iiterator> ret =
+ this->icont().equal_range(k, KeyNodeCompare(value_comp()));
+ return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
+ }
+
+ std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
+ {
+ std::pair<iiterator, iiterator> ret =
+ this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
+ return std::pair<const_iterator,const_iterator>
+ (const_iterator(ret.first), const_iterator(ret.second));
+ }
+
+ private:
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
+ {
+ if(unique){
+ for (; beg != end; ++beg){
+ this->insert_unique(*beg);
+ }
+ }
+ else{
+ for (; beg != end; ++beg){
+ this->insert_equal(*beg);
+ }
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+
+ public:
+ insertion_functor(Icont &icont)
+ : icont_(icont)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.insert_equal(this->icont_.cend(), n); }
+ };
+
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
+ {
+ if(beg != end){
+ if(unique){
+ priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
+ }
+ else{
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont()));
+ }
+ }
+ }
+
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_ordered_nodes
+ (InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+ {
+ const_iterator cend_n(this->cend());
+ for (; beg != end; ++beg){
+ this->insert_before(cend_n, *beg);
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_ordered_nodes
+ (InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_ordered_nodes(beg, end, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class back_insertion_functor;
+ friend class back_insertion_functor;
+
+ class back_insertion_functor
+ {
+ Icont &icont_;
+
+ public:
+ back_insertion_functor(Icont &icont)
+ : icont_(icont)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.push_back(n); }
+ };
+
+
+ template<class FwdIterator>
+ void priv_create_and_insert_ordered_nodes
+ (FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ if(beg != end){
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), back_insertion_functor(this->icont()));
+ }
+ }
+};
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
+{
+ return x.size() == y.size() &&
+ std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(),
+ y.begin(), y.end());
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return !(x == y);
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return y < x;
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return !(y < x);
+}
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline bool
+operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
+ return !(x < y);
+}
+
+
+template <class Key, class Value, class KeyOfValue,
+ class KeyCompare, class A>
+inline void
+swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
+ rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
+{
+ x.swap(y);
+}
+
+} //namespace containers_detail {
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class V, class KOV,
+class C, class A>
+struct has_trivial_destructor_after_move
+ <boost::container::containers_detail::rbtree<K, V, KOV, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINERS_TREE_HPP
Added: branches/release/boost/container/detail/type_traits.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/type_traits.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,203 @@
+//////////////////////////////////////////////////////////////////////////////
+// (C) Copyright John Maddock 2000.
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+// The alignment_of implementation comes from John Maddock's boost::alignment_of code
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+#define BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+
+#include <boost/move/move.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+struct nat{};
+
+//boost::alignment_of yields to 10K lines of preprocessed code, so we
+//need an alternative
+template <typename T> struct alignment_of;
+
+template <typename T>
+struct alignment_of_hack
+{
+ char c;
+ T t;
+ alignment_of_hack();
+};
+
+template <unsigned A, unsigned S>
+struct alignment_logic
+{
+ enum{ value = A < S ? A : S };
+};
+
+template< typename T >
+struct alignment_of
+{
+ enum{ value = alignment_logic
+ < sizeof(alignment_of_hack<T>) - sizeof(T)
+ , sizeof(T)>::value };
+};
+
+//This is not standard, but should work with all compilers
+union max_align
+{
+ char char_;
+ short short_;
+ int int_;
+ long long_;
+ #ifdef BOOST_HAS_LONG_LONG
+ long long long_long_;
+ #endif
+ float float_;
+ double double_;
+ long double long_double_;
+ void * void_ptr_;
+};
+
+template<class T>
+struct remove_reference
+{
+ typedef T type;
+};
+
+template<class T>
+struct remove_reference<T&>
+{
+ typedef T type;
+};
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template<class T>
+struct remove_reference<T&&>
+{
+ typedef T type;
+};
+
+#else
+
+template<class T>
+struct remove_reference< ::boost::rv<T> >
+{
+ typedef T type;
+};
+
+#endif
+
+template<class T>
+struct is_reference
+{
+ enum { value = false };
+};
+
+template<class T>
+struct is_reference<T&>
+{
+ enum { value = true };
+};
+
+template<class T>
+struct is_pointer
+{
+ enum { value = false };
+};
+
+template<class T>
+struct is_pointer<T*>
+{
+ enum { value = true };
+};
+
+template <typename T>
+struct add_reference
+{
+ typedef T& type;
+};
+
+template<class T>
+struct add_reference<T&>
+{
+ typedef T& type;
+};
+
+template<>
+struct add_reference<void>
+{
+ typedef nat &type;
+};
+
+template<>
+struct add_reference<const void>
+{
+ typedef const nat &type;
+};
+
+template <class T>
+struct add_const_reference
+{ typedef const T &type; };
+
+template <class T>
+struct add_const_reference<T&>
+{ typedef T& type; };
+
+template <typename T, typename U>
+struct is_same
+{
+ typedef char yes_type;
+ struct no_type
+ {
+ char padding[8];
+ };
+
+ template <typename V>
+ static yes_type is_same_tester(V*, V*);
+ static no_type is_same_tester(...);
+
+ static T *t;
+ static U *u;
+
+ static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
+};
+
+template<class T>
+struct remove_const
+{
+ typedef T type;
+};
+
+template<class T>
+struct remove_const< const T>
+{
+ typedef T type;
+};
+
+template<class T>
+struct remove_ref_const
+{
+ typedef typename remove_const< typename remove_reference<T>::type >::type type;
+};
+
+} // namespace containers_detail
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
Added: branches/release/boost/container/detail/utilities.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/utilities.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,150 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
+#define BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
+
+#include "config_begin.hpp"
+#include <cstdio>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_member_pointer.hpp>
+#include <boost/type_traits/is_class.hpp>
+#include <boost/move/move.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <algorithm>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class T>
+const T &max_value(const T &a, const T &b)
+{ return a > b ? a : b; }
+
+template<class T>
+const T &min_value(const T &a, const T &b)
+{ return a < b ? a : b; }
+
+template <class SizeType>
+SizeType
+ get_next_capacity(const SizeType max_size
+ ,const SizeType capacity
+ ,const SizeType n)
+{
+// if (n > max_size - capacity)
+// throw std::length_error("get_next_capacity");
+
+ const SizeType m3 = max_size/3;
+
+ if (capacity < m3)
+ return capacity + max_value(3*(capacity+1)/5, n);
+
+ if (capacity < m3*2)
+ return capacity + max_value((capacity+1)/2, n);
+
+ return max_size;
+}
+
+template<class SmartPtr>
+struct smart_ptr_type
+{
+ typedef typename SmartPtr::value_type value_type;
+ typedef value_type *pointer;
+ static pointer get (const SmartPtr &smartptr)
+ { return smartptr.get();}
+};
+
+template<class T>
+struct smart_ptr_type<T*>
+{
+ typedef T value_type;
+ typedef value_type *pointer;
+ static pointer get (pointer ptr)
+ { return ptr;}
+};
+
+//!Overload for smart pointers to avoid ADL problems with get_pointer
+template<class Ptr>
+inline typename smart_ptr_type<Ptr>::pointer
+get_pointer(const Ptr &ptr)
+{ return smart_ptr_type<Ptr>::get(ptr); }
+
+//!To avoid ADL problems with swap
+template <class T>
+inline void do_swap(T& x, T& y)
+{
+ using std::swap;
+ swap(x, y);
+}
+
+//Rounds "orig_size" by excess to round_to bytes
+template<class SizeType>
+inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
+{
+ return ((orig_size-1)/round_to+1)*round_to;
+}
+
+template <std::size_t OrigSize, std::size_t RoundTo>
+struct ct_rounded_size
+{
+ enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
+};
+
+template <class _TypeT>
+struct __rw_is_enum
+{
+struct _C_no { };
+struct _C_yes { int _C_dummy [2]; };
+
+struct _C_indirect {
+// prevent classes with user-defined conversions from matching
+
+// use double to prevent float->int gcc conversion warnings
+_C_indirect (double);
+};
+
+// nested struct gets rid of bogus gcc errors
+struct _C_nest {
+// supply first argument to prevent HP aCC warnings
+static _C_no _C_is (int, ...);
+static _C_yes _C_is (int, _C_indirect);
+
+static _TypeT _C_make_T ();
+};
+
+enum {
+_C_val = sizeof (_C_yes)
+== sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ()))
+&& !::boost::is_fundamental<_TypeT>::value
+};
+
+};
+
+template<class T>
+struct move_const_ref_type
+ : if_c
+// < ::boost::is_fundamental<T>::value || ::boost::is_pointer<T>::value || ::boost::is_member_pointer<T>::value || ::boost::is_enum<T>::value
+ < !::boost::is_class<T>::value
+ ,const T &
+ ,BOOST_CATCH_CONST_RLVALUE(T)
+ >
+{};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
Added: branches/release/boost/container/detail/value_init.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/value_init.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
+#define BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class T>
+struct value_init
+{
+ value_init()
+ : m_t()
+ {}
+
+ T m_t;
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
Added: branches/release/boost/container/detail/variadic_templates_tools.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/variadic_templates_tools.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,153 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+#define BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include "config_begin.hpp"
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <cstddef> //std::size_t
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<typename... Values>
+class tuple;
+
+template<> class tuple<>
+{};
+
+template<typename Head, typename... Tail>
+class tuple<Head, Tail...>
+ : private tuple<Tail...>
+{
+ typedef tuple<Tail...> inherited;
+
+ public:
+ tuple() { }
+
+ // implicit copy-constructor is okay
+ // Construct tuple from separate arguments.
+ tuple(typename add_const_reference<Head>::type v,
+ typename add_const_reference<Tail>::type... vtail)
+ : inherited(vtail...), m_head(v)
+ {}
+
+ // Construct tuple from another tuple.
+ template<typename... VValues>
+ tuple(const tuple<VValues...>& other)
+ : m_head(other.head()), inherited(other.tail())
+ {}
+
+ template<typename... VValues>
+ tuple& operator=(const tuple<VValues...>& other)
+ {
+ m_head = other.head();
+ tail() = other.tail();
+ return this;
+ }
+
+ typename add_reference<Head>::type head() { return m_head; }
+ typename add_reference<const Head>::type head() const { return m_head; }
+
+ inherited& tail() { return *this; }
+ const inherited& tail() const { return *this; }
+
+ protected:
+ Head m_head;
+};
+
+
+template<typename... Values>
+tuple<Values&&...> tie_forward(Values&&... values)
+{ return tuple<Values&&...>(values...); }
+
+template<int I, typename Tuple>
+struct tuple_element;
+
+template<int I, typename Head, typename... Tail>
+struct tuple_element<I, tuple<Head, Tail...> >
+{
+ typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct tuple_element<0, tuple<Head, Tail...> >
+{
+ typedef Head type;
+};
+
+template<int I, typename Tuple>
+class get_impl;
+
+template<int I, typename Head, typename... Values>
+class get_impl<I, tuple<Head, Values...> >
+{
+ typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
+ typedef get_impl<I-1, tuple<Values...> > Next;
+
+ public:
+ typedef typename add_reference<Element>::type type;
+ typedef typename add_const_reference<Element>::type const_type;
+ static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+ static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+};
+
+template<typename Head, typename... Values>
+class get_impl<0, tuple<Head, Values...> >
+{
+ public:
+ typedef typename add_reference<Head>::type type;
+ typedef typename add_const_reference<Head>::type const_type;
+ static type get(tuple<Head, Values...>& t) { return t.head(); }
+ static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
+};
+
+template<int I, typename... Values>
+typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
+{ return get_impl<I, tuple<Values...> >::get(t); }
+
+template<int I, typename... Values>
+typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
+{ return get_impl<I, tuple<Values...> >::get(t); }
+
+////////////////////////////////////////////////////
+// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
+// be used to "unpack" into comma-separated values
+// in a function call.
+////////////////////////////////////////////////////
+
+template<int... Indexes>
+struct index_tuple{};
+
+template<std::size_t Num, typename Tuple = index_tuple<> >
+struct build_number_seq;
+
+template<std::size_t Num, int... Indexes>
+struct build_number_seq<Num, index_tuple<Indexes...> >
+ : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
+{};
+
+template<int... Indexes>
+struct build_number_seq<0, index_tuple<Indexes...> >
+{ typedef index_tuple<Indexes...> type; };
+
+
+}}} //namespace boost { namespace container { namespace containers_detail {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
Added: branches/release/boost/container/detail/version_type.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/version_type.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This code comes from N1953 document by Howard E. Hinnant
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
+#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
+
+#include "config_begin.hpp"
+
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+namespace boost{
+namespace container {
+namespace containers_detail {
+
+//using namespace boost;
+
+template <class T, unsigned V>
+struct version_type
+ : public containers_detail::integral_constant<unsigned, V>
+{
+ typedef T type;
+
+ version_type(const version_type<T, 0>&);
+};
+
+namespace impl{
+
+template <class T,
+ bool = containers_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
+struct extract_version
+{
+ static const unsigned value = 1;
+};
+
+template <class T>
+struct extract_version<T, true>
+{
+ static const unsigned value = T::version::value;
+};
+
+template <class T>
+struct has_version
+{
+ private:
+ struct two {char _[2];};
+ template <class U> static two test(...);
+ template <class U> static char test(const typename U::version*);
+ public:
+ static const bool value = sizeof(test<T>(0)) == 1;
+ void dummy(){}
+};
+
+template <class T, bool = has_version<T>::value>
+struct version
+{
+ static const unsigned value = 1;
+};
+
+template <class T>
+struct version<T, true>
+{
+ static const unsigned value = extract_version<T>::value;
+};
+
+} //namespace impl
+
+template <class T>
+struct version
+ : public containers_detail::integral_constant<unsigned, impl::version<T>::value>
+{
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost{
+
+#include "config_end.hpp"
+
+#endif //#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
Added: branches/release/boost/container/detail/workaround.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/detail/workaround.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,24 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
+#define BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
+
+#include "config_begin.hpp"
+
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
+ && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
+#define BOOST_CONTAINERS_PERFECT_FORWARDING
+
+#endif
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
Added: branches/release/boost/container/flat_map.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/flat_map.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1443 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_FLAT_MAP_HPP
+#define BOOST_CONTAINERS_FLAT_MAP_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/container_fwd.hpp>
+#include <utility>
+#include <functional>
+#include <memory>
+#include <stdexcept>
+#include <boost/container/detail/flat_tree.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/move/move.hpp>
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators == and <, needed for friend declarations.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
+#else
+template <class Key, class T, class Pred, class A>
+#endif
+class flat_map;
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y);
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y);
+/// @endcond
+
+//! A flat_map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another
+//! type T based on the keys. The flat_map class supports random-access iterators.
+//!
+//! A flat_map satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. A flat_map also provides
+//! most operations described for unique keys. For a
+//! flat_map<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
+//! (unlike std::map<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! A is the allocator to allocate the value_types
+//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
+//!
+//! flat_map is similar to std::map but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_map invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_map invalidates iterators and references
+//! pointing to elements that come after (their keys are bigger) the erased element.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
+#else
+template <class Key, class T, class Pred, class A>
+#endif
+class flat_map
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_map)
+ //This is the tree that we should store if pair was movable
+ typedef containers_detail::flat_tree<Key,
+ std::pair<Key, T>,
+ containers_detail::select1st< std::pair<Key, T> >,
+ Pred,
+ A> tree_t;
+
+ //This is the real tree stored here. It's based on a movable pair
+ typedef containers_detail::flat_tree<Key,
+ containers_detail::pair<Key, T>,
+ containers_detail::select1st<containers_detail::pair<Key, T> >,
+ Pred,
+ typename A::template
+ rebind<containers_detail::pair<Key, T> >::other> impl_tree_t;
+ impl_tree_t m_flat_tree; // flat tree representing flat_map
+
+ typedef typename impl_tree_t::value_type impl_value_type;
+ typedef typename impl_tree_t::pointer impl_pointer;
+ typedef typename impl_tree_t::const_pointer impl_const_pointer;
+ typedef typename impl_tree_t::reference impl_reference;
+ typedef typename impl_tree_t::const_reference impl_const_reference;
+ typedef typename impl_tree_t::value_compare impl_value_compare;
+ typedef typename impl_tree_t::iterator impl_iterator;
+ typedef typename impl_tree_t::const_iterator impl_const_iterator;
+ typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
+ typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
+ typedef typename impl_tree_t::allocator_type impl_allocator_type;
+
+ template<class D, class S>
+ static D &force(const S &s)
+ { return *const_cast<D*>(reinterpret_cast<const D*>(&s)); }
+
+ template<class D, class S>
+ static D force_copy(S s)
+ {
+ value_type *vp = reinterpret_cast<value_type *>(&*s);
+ return D(vp);
+ }
+
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename impl_tree_t::key_type key_type;
+ typedef T mapped_type;
+ typedef typename std::pair<key_type, mapped_type> value_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef containers_detail::flat_tree_value_compare
+ < Pred
+ , containers_detail::select1st< std::pair<Key, T> >
+ , std::pair<Key, T> > value_compare;
+ typedef Pred key_compare;
+ typedef typename containers_detail::
+ get_flat_tree_iterators<pointer>::iterator iterator;
+ typedef typename containers_detail::
+ get_flat_tree_iterators<pointer>::const_iterator const_iterator;
+ typedef typename containers_detail::
+ get_flat_tree_iterators
+ <pointer>::reverse_iterator reverse_iterator;
+ typedef typename containers_detail::
+ get_flat_tree_iterators
+ <pointer>::const_reverse_iterator const_reverse_iterator;
+ typedef typename impl_tree_t::size_type size_type;
+ typedef typename impl_tree_t::difference_type difference_type;
+ typedef A allocator_type;
+ typedef A stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! comparison object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit flat_map(const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a)) {}
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a))
+ { m_flat_tree.insert_unique(first, last); }
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
+ //! <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)
+ : m_flat_tree(x.m_flat_tree) {}
+
+ //! <b>Effects</b>: Move constructs a flat_map.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_map(BOOST_RV_REF(flat_map) x)
+ : m_flat_tree(boost::move(x.m_flat_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_map<Key,T,Pred,A>& 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.
+ //! Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_map<Key,T,Pred,A>& 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
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return force<key_compare>(m_flat_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return force<allocator_type>(m_flat_tree.get_allocator()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return force_copy<iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return force<const_iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return force<const_iterator>(m_flat_tree.cbegin()); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return force_copy<iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return force<const_iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return force<const_iterator>(m_flat_tree.cend()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return force<reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return force<reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return force<const_reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return force<const_reverse_iterator>(m_flat_tree.crend()); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! Effects: If there is no key equivalent to x in the flat_map, inserts
+ //! value_type(x, T()) into the flat_map.
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T &operator[](const key_type& k)
+ {
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first))
+ i = insert(i, value_type(k, T()));
+ return (*i).second;
+ }
+
+ //! Effects: If there is no key equivalent to x in the flat_map, inserts
+ //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T &operator[](BOOST_RV_REF(key_type) mk)
+ {
+ key_type &k = mk;
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first))
+ i = insert(i, value_type(boost::move(k), boost::move(T())));
+ return (*i).second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ T& at(const key_type& k)
+ {
+ iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ const T& at(const key_type& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_map& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(const value_type& x)
+ { return force<std::pair<iterator,bool> >(
+ m_flat_tree.insert_unique(force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ { return force<std::pair<iterator,bool> >(
+ m_flat_tree.insert_unique(boost::move(force<impl_value_type>(x)))); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(impl_value_type) x)
+ {
+ return force<std::pair<iterator,bool> >
+ (m_flat_tree.insert_unique(boost::move(x)));
+ }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, const value_type& x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), boost::move(force<impl_value_type>(x)))); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
+ {
+ return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), boost::move(x)));
+ }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint), boost::forward<Args>(args)...)); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return force_copy<iterator>(m_flat_tree.emplace_unique()); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint))); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_unique \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_hint_unique \
+ (force<impl_const_iterator>(hint), \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.s
+ const_iterator find(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
+ { return force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const flat_map<K1, T1, C1, A1>&,
+ const flat_map<K1, T1, C1, A1>&);
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const flat_map<K1, T1, C1, A1>&,
+ const flat_map<K1, T1, C1, A1>&);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator!=(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y)
+ { return !(x == y); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y)
+ { return y < x; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<=(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y)
+ { return !(y < x); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>=(const flat_map<Key,T,Pred,A>& x,
+ const flat_map<Key,T,Pred,A>& y)
+ { return !(x < y); }
+
+template <class Key, class T, class Pred, class A>
+inline void swap(flat_map<Key,T,Pred,A>& x,
+ flat_map<Key,T,Pred,A>& y)
+ { x.swap(y); }
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
+#else
+template <class Key, class T, class Pred, class A>
+#endif
+class flat_multimap;
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y);
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y);
+/// @endcond
+
+//! A flat_multimap is a kind of associative container that supports equivalent keys
+//! (possibly containing multiple copies of the same key value) and provides for
+//! fast retrieval of values of another type T based on the keys. The flat_multimap
+//! class supports random-access iterators.
+//!
+//! A flat_multimap satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! flat_multimap<Key,T> the key_type is Key and the value_type is std::pair<Key,T>
+//! (unlike std::multimap<Key, T> which value_type is std::pair<<b>const</b> Key, T>).
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! A is the allocator to allocate the value_types
+//! (e.g. <i>allocator< std::pair<Key, T> ></i>).
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Pred = std::less< std::pair< Key, T> >, class A = std::allocator<T> >
+#else
+template <class Key, class T, class Pred, class A>
+#endif
+class flat_multimap
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
+ typedef containers_detail::flat_tree<Key,
+ std::pair<Key, T>,
+ containers_detail::select1st< std::pair<Key, T> >,
+ Pred,
+ A> tree_t;
+ //This is the real tree stored here. It's based on a movable pair
+ typedef containers_detail::flat_tree<Key,
+ containers_detail::pair<Key, T>,
+ containers_detail::select1st<containers_detail::pair<Key, T> >,
+ Pred,
+ typename A::template
+ rebind<containers_detail::pair<Key, T> >::other> impl_tree_t;
+ impl_tree_t m_flat_tree; // flat tree representing flat_map
+
+ typedef typename impl_tree_t::value_type impl_value_type;
+ typedef typename impl_tree_t::pointer impl_pointer;
+ typedef typename impl_tree_t::const_pointer impl_const_pointer;
+ typedef typename impl_tree_t::reference impl_reference;
+ typedef typename impl_tree_t::const_reference impl_const_reference;
+ typedef typename impl_tree_t::value_compare impl_value_compare;
+ typedef typename impl_tree_t::iterator impl_iterator;
+ typedef typename impl_tree_t::const_iterator impl_const_iterator;
+ typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
+ typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
+ typedef typename impl_tree_t::allocator_type impl_allocator_type;
+
+ template<class D, class S>
+ static D &force(const S &s)
+ { return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
+
+ template<class D, class S>
+ static D force_copy(S s)
+ {
+ value_type *vp = reinterpret_cast<value_type *>(&*s);
+ return D(vp);
+ }
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename impl_tree_t::key_type key_type;
+ typedef T mapped_type;
+ typedef typename std::pair<key_type, mapped_type> value_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef containers_detail::flat_tree_value_compare
+ < Pred
+ , containers_detail::select1st< std::pair<Key, T> >
+ , std::pair<Key, T> > value_compare;
+ typedef Pred key_compare;
+ typedef typename containers_detail::
+ get_flat_tree_iterators<pointer>::iterator iterator;
+ typedef typename containers_detail::
+ get_flat_tree_iterators<pointer>::const_iterator const_iterator;
+ typedef typename containers_detail::
+ get_flat_tree_iterators
+ <pointer>::reverse_iterator reverse_iterator;
+ typedef typename containers_detail::
+ get_flat_tree_iterators
+ <pointer>::const_reverse_iterator const_reverse_iterator;
+ typedef typename impl_tree_t::size_type size_type;
+ typedef typename impl_tree_t::difference_type difference_type;
+ typedef A allocator_type;
+ typedef A stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
+ //! object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit flat_multimap(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a)) { }
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_multimap(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, force<impl_allocator_type>(a))
+ { m_flat_tree.insert_equal(first, last); }
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_multimap(ordered_range_t, InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
+ //! <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)
+ : m_flat_tree(x.m_flat_tree) { }
+
+ //! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_multimap(BOOST_RV_REF(flat_multimap) x)
+ : m_flat_tree(boost::move(x.m_flat_tree))
+ { }
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_multimap<Key,T,Pred,A>& 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)
+ { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return force<key_compare>(m_flat_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return force<allocator_type>(m_flat_tree.get_allocator()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return force_copy<iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return force<const_iterator>(m_flat_tree.begin()); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return force_copy<iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return force<const_iterator>(m_flat_tree.end()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return force<reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return force<reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return force<const_reverse_iterator>(m_flat_tree.rend()); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_multimap& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const value_type& x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(BOOST_RV_REF(value_type) x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(BOOST_RV_REF(impl_value_type) x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, const value_type& x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
+
+ //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
+ {
+ return force_copy<iterator>
+ (m_flat_tree.insert_equal(force<impl_const_iterator>(position)
+ , boost::move(x)));
+ }
+
+ //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
+ {
+ return force_copy<iterator>(
+ m_flat_tree.insert_equal(force<impl_const_iterator>(position), boost::move(x)));
+ }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) .
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ {
+ return force_copy<iterator>(m_flat_tree.emplace_hint_equal
+ (force<impl_const_iterator>(hint), boost::forward<Args>(args)...));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return force_copy<iterator>(m_flat_tree.emplace_equal()); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_equal(force<impl_const_iterator>(hint))); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_equal \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_hint_equal \
+ (force<impl_const_iterator>(hint), \
+ BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return force_copy<iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: An const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.find(x)); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ {return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key
+ //! not less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.lower_bound(x)); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ {return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key
+ //! not less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return force<const_iterator>(m_flat_tree.upper_bound(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& x) const
+ { return force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const flat_multimap<K1, T1, C1, A1>& x,
+ const flat_multimap<K1, T1, C1, A1>& y);
+
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const flat_multimap<K1, T1, C1, A1>& x,
+ const flat_multimap<K1, T1, C1, A1>& y);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator!=(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y)
+ { return !(x == y); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y)
+ { return y < x; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<=(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y)
+ { return !(y < x); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>=(const flat_multimap<Key,T,Pred,A>& x,
+ const flat_multimap<Key,T,Pred,A>& y)
+ { return !(x < y); }
+
+template <class Key, class T, class Pred, class A>
+inline void swap(flat_multimap<Key,T,Pred,A>& x, flat_multimap<Key,T,Pred,A>& y)
+ { x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+} //namespace boost {
+
+/// @endcond
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_FLAT_MAP_HPP */
Added: branches/release/boost/container/flat_set.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/flat_set.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1261 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_FLAT_SET_HPP
+#define BOOST_CONTAINERS_FLAT_SET_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/container_fwd.hpp>
+#include <utility>
+#include <functional>
+#include <memory>
+#include <boost/container/detail/flat_tree.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/move/move.hpp>
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators < and ==, needed for friend declaration.
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
+#else
+template <class T, class Pred, class A>
+#endif
+class flat_set;
+
+template <class T, class Pred, class A>
+inline bool operator==(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y);
+
+template <class T, class Pred, class A>
+inline bool operator<(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y);
+/// @endcond
+
+//! flat_set is a Sorted Associative Container that stores objects of type Key.
+//! flat_set is a Simple Associative Container, meaning that its value type,
+//! as well as its key type, is Key. It is also a Unique Associative Container,
+//! meaning that no two elements are the same.
+//!
+//! flat_set is similar to std::set but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_set invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_set invalidates iterators and references
+//! pointing to elements that come after (their keys are bigger) the erased element.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
+#else
+template <class T, class Pred, class A>
+#endif
+class flat_set
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_set)
+ typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, A> tree_t;
+ tree_t m_flat_tree; // flat tree representing flat_set
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef typename tree_t::key_compare key_compare;
+ typedef typename tree_t::value_compare value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! comparison object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit flat_set(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_set(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a)
+ { m_flat_tree.insert_unique(first, last); }
+
+ //! <b>Effects</b>: Constructs an empty flat_set using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_set(ordered_unique_range_t, InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a map.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set(const flat_set<T,Pred,A>& x)
+ : m_flat_tree(x.m_flat_tree) {}
+
+ //! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ flat_set(BOOST_RV_REF(flat_set) mx)
+ : m_flat_tree(boost::move(mx.m_flat_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ flat_set<T,Pred,A>& 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>Complexity</b>: Linear in x.size().
+ flat_set<T,Pred,A>& 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
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_flat_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_flat_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_flat_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_flat_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_flat_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_flat_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_flat_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_set& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator, bool> insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ std::pair<iterator, bool> insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ std::pair<iterator, bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ { return m_flat_tree.insert_unique(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
+ { return m_flat_tree.insert_unique(position, boost::move(x)); }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_flat_tree.emplace_unique(boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_flat_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_flat_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_flat_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return m_flat_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_flat_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.s
+ const_iterator find(const key_type& x) const
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
+
+ template <class K1, class C1, class A1>
+ friend bool operator< (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
+
+ private:
+ std::pair<iterator, bool> priv_insert(const T &x)
+ { return m_flat_tree.insert_unique(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_flat_tree.insert_unique(p, x); }
+ /// @endcond
+};
+
+template <class T, class Pred, class A>
+inline bool operator==(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator<(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator!=(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y)
+ { return !(x == y); }
+
+template <class T, class Pred, class A>
+inline bool operator>(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y)
+ { return y < x; }
+
+template <class T, class Pred, class A>
+inline bool operator<=(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y)
+ { return !(y < x); }
+
+template <class T, class Pred, class A>
+inline bool operator>=(const flat_set<T,Pred,A>& x,
+ const flat_set<T,Pred,A>& y)
+ { return !(x < y); }
+
+template <class T, class Pred, class A>
+inline void swap(flat_set<T,Pred,A>& x, flat_set<T,Pred,A>& y)
+ { x.swap(y); }
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::flat_set<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value &&has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
+#else
+template <class T, class Pred, class A>
+#endif
+class flat_multiset;
+
+template <class T, class Pred, class A>
+inline bool operator==(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y);
+
+template <class T, class Pred, class A>
+inline bool operator<(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y);
+/// @endcond
+
+//! flat_multiset is a Sorted Associative Container that stores objects of type Key.
+//! flat_multiset is a Simple Associative Container, meaning that its value type,
+//! as well as its key type, is Key.
+//! flat_Multiset can store multiple copies of the same key value.
+//!
+//! flat_multiset is similar to std::multiset but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_multiset invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_multiset invalidates iterators and references
+//! pointing to elements that come after (their keys are equal or bigger) the erased element.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
+#else
+template <class T, class Pred, class A>
+#endif
+class flat_multiset
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
+ typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, A> tree_t;
+ tree_t m_flat_tree; // flat tree representing flat_multiset
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
+ /// @endcond
+
+ public:
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef typename tree_t::key_compare key_compare;
+ typedef typename tree_t::value_compare value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ // allocation/deallocation
+ explicit flat_multiset(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a) {}
+
+ template <class InputIterator>
+ flat_multiset(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(comp, a)
+ { m_flat_tree.insert_equal(first, last); }
+
+ //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_multiset(ordered_range_t, InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : 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) {}
+
+ flat_multiset(BOOST_RV_REF(flat_multiset) x)
+ : m_flat_tree(boost::move(x.m_flat_tree))
+ {}
+
+ flat_multiset<T,Pred,A>& 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)
+ { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_flat_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_flat_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_flat_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_flat_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_flat_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_flat_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_flat_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_flat_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_flat_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_flat_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_flat_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_flat_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_flat_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_flat_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_flat_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(flat_multiset& x)
+ { m_flat_tree.swap(x.m_flat_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from x
+ //! and returns the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(BOOST_RV_REF(value_type) x)
+ { return m_flat_tree.insert_equal(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
+ { return m_flat_tree.insert_equal(position, boost::move(x)); }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) .
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ //! search time plus N*size() insertion time.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_flat_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_flat_tree.emplace_equal(boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_flat_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_flat_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_flat_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Linear to the elements with keys bigger than position
+ //!
+ //! <b>Note</b>: Invalidates elements with keys
+ //! not less than the erased element.
+ iterator erase(const_iterator position)
+ { return m_flat_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ size_type erase(const key_type& x)
+ { return m_flat_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: size()*N where N is the distance from first to last.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus erasure time
+ //! linear to the elements with bigger keys.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_flat_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_flat_tree.clear(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ // with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { m_flat_tree.shrink_to_fit(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.s
+ const_iterator find(const key_type& x) const
+ { return m_flat_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_flat_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_flat_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_flat_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_flat_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return m_flat_tree.capacity(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! to values might be invalidated.
+ void reserve(size_type count)
+ { m_flat_tree.reserve(count); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const flat_multiset<K1,C1,A1>&,
+ const flat_multiset<K1,C1,A1>&);
+ template <class K1, class C1, class A1>
+ friend bool operator< (const flat_multiset<K1,C1,A1>&,
+ const flat_multiset<K1,C1,A1>&);
+ private:
+ iterator priv_insert(const T &x)
+ { return m_flat_tree.insert_equal(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_flat_tree.insert_equal(p, x); }
+ /// @endcond
+};
+
+template <class T, class Pred, class A>
+inline bool operator==(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y)
+ { return x.m_flat_tree == y.m_flat_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator<(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y)
+ { return x.m_flat_tree < y.m_flat_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator!=(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y)
+ { return !(x == y); }
+
+template <class T, class Pred, class A>
+inline bool operator>(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y)
+ { return y < x; }
+
+template <class T, class Pred, class A>
+inline bool operator<=(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y)
+ { return !(y < x); }
+
+template <class T, class Pred, class A>
+inline bool operator>=(const flat_multiset<T,Pred,A>& x,
+ const flat_multiset<T,Pred,A>& y)
+{ return !(x < y); }
+
+template <class T, class Pred, class A>
+inline void swap(flat_multiset<T,Pred,A>& x, flat_multiset<T,Pred,A>& y)
+ { x.swap(y); }
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::flat_multiset<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_FLAT_SET_HPP */
Added: branches/release/boost/container/list.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/list.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1373 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+
+#ifndef BOOST_CONTAINERS_LIST_HPP_
+#define BOOST_CONTAINERS_LIST_HPP_
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/move/move.hpp>
+#include <boost/move/move_helpers.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/algorithms.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/intrusive/list.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+
+#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#else
+//Preprocessor library to emulate perfect forwarding
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+#include <stdexcept>
+#include <iterator>
+#include <utility>
+#include <memory>
+#include <functional>
+#include <algorithm>
+#include <stdexcept>
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+namespace containers_detail {
+
+template<class VoidPointer>
+struct list_hook
+{
+ typedef typename containers_detail::bi::make_list_base_hook
+ <containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
+};
+
+template <class T, class VoidPointer>
+struct list_node
+ : public list_hook<VoidPointer>::type
+{
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ list_node()
+ : m_data()
+ {}
+
+ template<class ...Args>
+ list_node(Args &&...args)
+ : m_data(boost::forward<Args>(args)...)
+ {}
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ list_node()
+ : m_data()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ list_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ T m_data;
+};
+
+template<class A>
+struct intrusive_list_type
+{
+ typedef typename A::value_type value_type;
+ typedef typename boost::pointer_to_other
+ <typename A::pointer, void>::type void_pointer;
+ typedef typename containers_detail::list_node
+ <value_type, void_pointer> node_type;
+ typedef typename containers_detail::bi::make_list
+ < node_type
+ , containers_detail::bi::base_hook<typename list_hook<void_pointer>::type>
+ , containers_detail::bi::constant_time_size<true>
+ , containers_detail::bi::size_type<typename A::size_type>
+ >::type container_type;
+ typedef container_type type ;
+};
+
+} //namespace containers_detail {
+/// @endcond
+
+//! A list is a doubly linked list. That is, it is a Sequence that supports both
+//! forward and backward traversal, and (amortized) constant time insertion and
+//! removal of elements at the beginning or the end, or in the middle. Lists have
+//! the important property that insertion and splicing do not invalidate iterators
+//! to list elements, and that even removal invalidates only the iterators that point
+//! to the elements that are removed. The ordering of iterators may be changed
+//! (that is, list<T>::iterator might have a different predecessor or successor
+//! after a list operation than it did before), but the iterators themselves will
+//! not be invalidated or made to point to different elements unless that invalidation
+//! or mutation is explicit.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class A = std::allocator<T> >
+#else
+template <class T, class A>
+#endif
+class list
+ : protected containers_detail::node_alloc_holder
+ <A, typename containers_detail::intrusive_list_type<A>::type>
+{
+ /// @cond
+ typedef typename
+ containers_detail::intrusive_list_type<A>::type Icont;
+ typedef list <T, A> ThisType;
+ typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::allocator_v1 allocator_v1;
+ typedef typename AllocHolder::allocator_v2 allocator_v2;
+ typedef typename AllocHolder::alloc_version alloc_version;
+
+ class equal_to_value
+ {
+ typedef typename AllocHolder::value_type value_type;
+ const value_type &t_;
+
+ public:
+ equal_to_value(const value_type &t)
+ : t_(t)
+ {}
+
+ bool operator()(const value_type &t)const
+ { return t_ == t; }
+ };
+
+ template<class Pred>
+ struct ValueCompareToNodeCompare
+ : Pred
+ {
+ ValueCompareToNodeCompare(Pred pred)
+ : Pred(pred)
+ {}
+
+ bool operator()(const Node &a, const Node &b) const
+ { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
+
+ bool operator()(const Node &a) const
+ { return static_cast<const Pred&>(*this)(a.m_data); }
+ };
+ /// @endcond
+
+ public:
+ //! The type of object, T, stored in the list
+ typedef T value_type;
+ //! Pointer to T
+ typedef typename A::pointer pointer;
+ //! Const pointer to T
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to T
+ typedef typename A::reference reference;
+ //! Const reference to T
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! The allocator type
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef NodeAlloc stored_allocator_type;
+
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(list)
+ typedef difference_type list_difference_type;
+ typedef pointer list_pointer;
+ typedef const_pointer list_const_pointer;
+ typedef reference list_reference;
+ typedef const_reference list_const_reference;
+ /// @endcond
+
+ public:
+ //! Const iterator used to iterate through a list.
+ class const_iterator
+ /// @cond
+ : public std::iterator<std::bidirectional_iterator_tag,
+ value_type, list_difference_type,
+ list_const_pointer, list_const_reference>
+ {
+
+ protected:
+ typename Icont::iterator m_it;
+ explicit const_iterator(typename Icont::iterator it) : m_it(it){}
+ void prot_incr() { ++m_it; }
+ void prot_decr() { --m_it; }
+
+ private:
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class list<T, A>;
+ typedef list_difference_type difference_type;
+
+ //Constructors
+ const_iterator()
+ : m_it()
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return m_it->m_data; }
+
+ const_pointer operator->() const
+ { return const_pointer(&m_it->m_data); }
+
+ //Increment / Decrement
+ const_iterator& operator++()
+ { prot_incr(); return *this; }
+
+ const_iterator operator++(int)
+ { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
+
+ const_iterator& operator--()
+ { prot_decr(); return *this; }
+
+ const_iterator operator--(int)
+ { typename Icont::iterator tmp = m_it; --*this; return const_iterator(tmp); }
+
+ //Comparison operators
+ bool operator== (const const_iterator& r) const
+ { return m_it == r.m_it; }
+
+ bool operator!= (const const_iterator& r) const
+ { return m_it != r.m_it; }
+ }
+ /// @endcond
+ ;
+
+ //! Iterator used to iterate through a list
+ class iterator
+ /// @cond
+ : public const_iterator
+ {
+
+ private:
+ explicit iterator(typename Icont::iterator it)
+ : const_iterator(it)
+ {}
+
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class list<T, A>;
+ typedef list_pointer pointer;
+ typedef list_reference reference;
+
+ //Constructors
+ iterator(){}
+
+ //Pointer like operators
+ reference operator*() const { return this->m_it->m_data; }
+ pointer operator->() const { return pointer(&this->m_it->m_data); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->prot_incr(); return *this; }
+
+ iterator operator++(int)
+ { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
+
+ iterator& operator--()
+ { this->prot_decr(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp = *this; --*this; return tmp; }
+ };
+ /// @endcond
+
+ //! Iterator used to iterate backwards through a list.
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ //! Const iterator used to iterate backwards through a list.
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit list(const allocator_type &a = A())
+ : AllocHolder(a)
+ {}
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ list(size_type n)
+ : AllocHolder(A())
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ list(size_type n, const T& value, const A& a = A())
+ : AllocHolder(a)
+ { this->insert(this->cbegin(), n, value); }
+
+ //! <b>Effects</b>: Copy constructs a list.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ list(const list& x)
+ : AllocHolder(x)
+ { this->insert(this->cbegin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ list(BOOST_RV_REF(list) x)
+ : AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
+ {}
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the list.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InpIt>
+ list(InpIt first, InpIt last, const A &a = A())
+ : AllocHolder(a)
+ { this->insert(this->cbegin(), first, last); }
+
+ //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~list()
+ {} //AllocHolder clears the list
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ //! <b>Effects</b>: Erases all the elements of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the list.
+ void clear()
+ { AllocHolder::clear(alloc_version()); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return iterator(this->icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return iterator(this->icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(begin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->cend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->cbegin()); }
+
+ //! <b>Effects</b>: Returns true if the list contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->size(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->icont().size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return AllocHolder::max_size(); }
+
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(const T &x);
+
+ //! <b>Effects</b>: Constructs a new element in the beginning of the list
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+ #endif
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the end of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(const T &x);
+
+ //! <b>Effects</b>: Constructs a new element in the end of the list
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+ #endif
+
+ //! <b>Effects</b>: Removes the first element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void pop_front()
+ { this->erase(this->cbegin()); }
+
+ //! <b>Effects</b>: Removes the last element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void pop_back()
+ { const_iterator tmp = this->cend(); this->erase(--tmp); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return *this->begin(); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->begin(); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back()
+ { return *(--this->end()); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back() const
+ { return *(--this->end()); }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ const_iterator iend = this->cend();
+ size_type len = this->size();
+
+ if(len > new_size){
+ size_type to_erase = len - new_size;
+ while(to_erase--){
+ --iend;
+ }
+ this->erase(iend, this->cend());
+ }
+ else{
+ this->priv_create_and_insert_nodes(iend, new_size - len, x);
+ }
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ const_iterator iend = this->end();
+ size_type len = this->size();
+
+ if(len > new_size){
+ size_type to_erase = len - new_size;
+ const_iterator ifirst;
+ if(to_erase < len/2u){
+ ifirst = iend;
+ while(to_erase--){
+ --ifirst;
+ }
+ }
+ else{
+ ifirst = this->begin();
+ size_type to_skip = len - to_erase;
+ while(to_skip--){
+ ++ifirst;
+ }
+ }
+ this->erase(ifirst, iend);
+ }
+ else{
+ this->priv_create_and_insert_nodes(this->cend(), new_size - len);
+ }
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(ThisType& x)
+ { AllocHolder::swap(x); }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ ThisType& operator=(BOOST_COPY_ASSIGN_REF(ThisType) x)
+ {
+ if (this != &x) {
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ ThisType& operator=(BOOST_RV_REF(ThisType) mx)
+ {
+ this->clear();
+ this->swap(mx);
+ return *this;
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void insert(const_iterator p, size_type n, const T& x)
+ { this->priv_create_and_insert_nodes(p, n, x); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last).
+ template <class InpIt>
+ void insert(const_iterator p, InpIt first, InpIt last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(p, first, last, Result());
+ }
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before position.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator insert(const_iterator position, const T &x);
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before position with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator insert(const_iterator position, T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+ #endif
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ {
+ this->emplace(this->cend(), boost::forward<Args>(args)...);
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ {
+ this->emplace(this->cbegin(), boost::forward<Args>(args)...);
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node(boost::forward<Args>(args)...);
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert(p.get(), *node));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_back()
+ { this->emplace(this->cend()); }
+
+ void emplace_front()
+ { this->emplace(this->cbegin()); }
+
+ iterator emplace(const_iterator p)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node();
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert(p.get(), *node));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace(this->cend(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { this->emplace(this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));} \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
+ new ((void*)containers_detail::get_pointer(d.get())) \
+ Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ NodePtr node = d.get(); \
+ d.release(); \
+ return iterator(this->icont().insert(p.get(), *node)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Erases the element at p p.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator erase(const_iterator p)
+ { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
+
+ //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+ //!
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InpIt>
+ void assign(InpIt first, InpIt last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType& x)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont());
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType &x, const_iterator i)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont(), i.get());
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements transferred.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont(), first.get(), last.get());
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //! n == std::distance(first, last)
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
+ }
+ else{
+ throw std::runtime_error("list::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Effects</b>: Reverses the order of elements in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time.
+ //!
+ //! <b>Note</b>: Iterators and references are not invalidated
+ void reverse()
+ { this->icont().reverse(); }
+
+ //! <b>Effects</b>: Removes all the elements that compare equal to value.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void remove(const T& value)
+ { remove_if(equal_to_value(value)); }
+
+ //! <b>Effects</b>: Removes all the elements for which a specified
+ //! predicate is satisfied.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class Pred>
+ void remove_if(Pred pred)
+ {
+ typedef ValueCompareToNodeCompare<Pred> Predicate;
+ this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that are equal from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void unique()
+ { this->unique(value_equal()); }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that satisfy some binary predicate from the list.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class BinaryPredicate>
+ void unique(BinaryPredicate binary_pred)
+ {
+ typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
+ this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Requires</b>: The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this according to std::less<value_type>. The merge is stable;
+ //! that is, if an element from *this is equivalent to one from x, then the element
+ //! from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ void merge(list<T, A>& x)
+ { this->merge(x, value_less()); }
+
+ //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+ //! ordering and both *this and x must be sorted according to that ordering
+ //! The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this. The merge is stable; that is, if an element from *this is
+ //! equivalent to one from x, then the element from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ //!
+ //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ template <class StrictWeakOrdering>
+ void merge(list &x, StrictWeakOrdering comp)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+ else{
+ throw std::runtime_error("list::merge called with unequal allocators");
+ }
+ }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ void sort()
+ { this->sort(value_less()); }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ template <class StrictWeakOrdering>
+ void sort(StrictWeakOrdering comp)
+ {
+ // nothing if the list has length 0 or 1.
+ if (this->size() < 2)
+ return;
+ this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+
+ /// @cond
+ private:
+
+ iterator priv_insert(const_iterator p, const T &x)
+ {
+ NodePtr tmp = AllocHolder::create_node(x);
+ return iterator(this->icont().insert(p.get(), *tmp));
+ }
+
+ iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
+ {
+ NodePtr tmp = AllocHolder::create_node(boost::move(x));
+ return iterator(this->icont().insert(p.get(), *tmp));
+ }
+
+ void priv_push_back (const T &x)
+ { this->insert(this->cend(), x); }
+
+ void priv_push_back (BOOST_RV_REF(T) x)
+ { this->insert(this->cend(), boost::move(x)); }
+
+ void priv_push_front (const T &x)
+ { this->insert(this->cbegin(), x); }
+
+ void priv_push_front (BOOST_RV_REF(T) x)
+ { this->insert(this->cbegin(), boost::move(x)); }
+
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, InpIterator beg, InpIterator end)
+ {
+ typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(pos, beg, end, alloc_version(), ItCat());
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+ {
+ for (; beg != end; ++beg){
+ this->icont().insert(pos.get(), *this->create_node_from_it(beg));
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+ typename Icont::const_iterator pos_;
+
+ public:
+ insertion_functor(Icont &icont, typename Icont::const_iterator pos)
+ : icont_(icont), pos_(pos)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.insert(pos_, n); }
+ };
+
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ if(beg != end){
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
+ }
+ }
+
+ //Default constructed version
+ void priv_create_and_insert_nodes(const_iterator pos, size_type n)
+ {
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->priv_create_and_insert_nodes(pos, default_iterator(n), default_iterator());
+ }
+
+ //Copy constructed version
+ void priv_create_and_insert_nodes(const_iterator pos, size_type n, const T& x)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->priv_create_and_insert_nodes(pos, cvalue_iterator(x, n), cvalue_iterator());
+ }
+
+ //Dispatch to detect iterator range or integer overloads
+ template <class InputIter>
+ void priv_insert_dispatch(const_iterator p,
+ InputIter first, InputIter last,
+ containers_detail::false_)
+ { this->priv_create_and_insert_nodes(p, first, last); }
+
+ template<class Integer>
+ void priv_insert_dispatch(const_iterator p, Integer n, Integer x, containers_detail::true_)
+ { this->insert(p, (size_type)n, x); }
+
+ void priv_fill_assign(size_type n, const T& val)
+ {
+ iterator i = this->begin(), iend = this->end();
+
+ for ( ; i != iend && n > 0; ++i, --n)
+ *i = val;
+ if (n > 0){
+ this->priv_create_and_insert_nodes(this->cend(), n, val);
+ }
+ else{
+ this->erase(i, cend());
+ }
+ }
+
+ template <class Integer>
+ void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
+ { this->priv_fill_assign((size_type) n, (T) val); }
+
+ template <class InputIter>
+ void priv_assign_dispatch(InputIter first2, InputIter last2, containers_detail::false_)
+ {
+ iterator first1 = this->begin();
+ iterator last1 = this->end();
+ for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+ *first1 = *first2;
+ if (first2 == last2)
+ this->erase(first1, last1);
+ else{
+ this->priv_create_and_insert_nodes(last1, first2, last2);
+ }
+ }
+
+ //Functors for member algorithm defaults
+ struct value_less
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a < b; }
+ };
+
+ struct value_equal
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a == b; }
+ };
+ /// @endcond
+
+};
+
+template <class T, class A>
+inline bool operator==(const list<T,A>& x, const list<T,A>& y)
+{
+ if(x.size() != y.size()){
+ return false;
+ }
+ typedef typename list<T,A>::const_iterator const_iterator;
+ const_iterator end1 = x.end();
+
+ const_iterator i1 = x.begin();
+ const_iterator i2 = y.begin();
+ while (i1 != end1 && *i1 == *i2) {
+ ++i1;
+ ++i2;
+ }
+ return i1 == end1;
+}
+
+template <class T, class A>
+inline bool operator<(const list<T,A>& x,
+ const list<T,A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T, class A>
+inline bool operator!=(const list<T,A>& x, const list<T,A>& y)
+{
+ return !(x == y);
+}
+
+template <class T, class A>
+inline bool operator>(const list<T,A>& x, const list<T,A>& y)
+{
+ return y < x;
+}
+
+template <class T, class A>
+inline bool operator<=(const list<T,A>& x, const list<T,A>& y)
+{
+ return !(y < x);
+}
+
+template <class T, class A>
+inline bool operator>=(const list<T,A>& x, const list<T,A>& y)
+{
+ return !(x < y);
+}
+
+template <class T, class A>
+inline void swap(list<T, A>& x, list<T, A>& y)
+{
+ x.swap(y);
+}
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::container::list<T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_LIST_HPP_
Added: branches/release/boost/container/map.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/map.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1292 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_MAP_HPP
+#define BOOST_CONTAINERS_MAP_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/container_fwd.hpp>
+#include <utility>
+#include <functional>
+#include <memory>
+#include <stdexcept>
+#include <boost/container/detail/tree.hpp>
+#include <boost/container/detail/value_init.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/move/move.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators == and <, needed for friend declarations.
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y);
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y);
+/// @endcond
+
+//! A map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another
+//! type T based on the keys. The map class supports bidirectional iterators.
+//!
+//! A map satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! A is the allocator to allocate the value_types
+//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Pred = std::less< std::pair< const Key, T> >, class A = std::allocator<T> >
+#else
+template <class Key, class T, class Pred, class A>
+#endif
+class map
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(map)
+ typedef containers_detail::rbtree<Key,
+ std::pair<const Key, T>,
+ containers_detail::select1st< std::pair<const Key, T> >,
+ Pred,
+ A> tree_t;
+ tree_t m_tree; // red-black tree representing map
+
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef T mapped_type;
+ typedef Pred key_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+ typedef std::pair<key_type, mapped_type> nonconst_value_type;
+ typedef containers_detail::pair
+ <key_type, mapped_type> nonconst_impl_value_type;
+
+ /// @cond
+ class value_compare_impl
+ : public Pred,
+ public std::binary_function<value_type, value_type, bool>
+ {
+ friend class map<Key,T,Pred,A>;
+ protected :
+ value_compare_impl(const Pred &c) : Pred(c) {}
+ public:
+ bool operator()(const value_type& x, const value_type& y) const {
+ return Pred::operator()(x.first, y.first);
+ }
+ };
+ /// @endcond
+ typedef value_compare_impl value_compare;
+
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object
+ //! and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit map(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, true)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ map( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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)
+ : m_tree(x.m_tree)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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>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((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ map& operator=(BOOST_COPY_ASSIGN_REF(map) x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ map& operator=(BOOST_RV_REF(map) x)
+ { m_tree = boost::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(m_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! Effects: If there is no key equivalent to x in the map, inserts
+ //! value_type(x, T()) into the map.
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T& operator[](const key_type& k)
+ {
+ //we can optimize this
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first)){
+ containers_detail::value_init<T> v;
+ value_type val(k, boost::move(v.m_t));
+ i = insert(i, boost::move(val));
+ }
+ return (*i).second;
+ }
+
+ //! Effects: If there is no key equivalent to x in the map, inserts
+ //! value_type(boost::move(x), T()) into the map (the key is move-constructed)
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ T& operator[](BOOST_RV_REF(key_type) mk)
+ {
+ key_type &k = mk;
+ //we can optimize this
+ iterator i = lower_bound(k);
+ // i->first is greater than or equivalent to k.
+ if (i == end() || key_comp()(k, (*i).first)){
+ value_type val(boost::move(k), boost::move(T()));
+ i = insert(i, boost::move(val));
+ }
+ return (*i).second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ T& at(const key_type& k)
+ {
+ iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ const T& at(const key_type& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(map& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(const value_type& x)
+ { return m_tree.insert_unique(x); }
+
+ //! <b>Effects</b>: Inserts a new value_type created from the pair if and only if
+ //! there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(const nonconst_value_type& x)
+ { return m_tree.insert_unique(x); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_unique(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
+ //! only if there is no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_unique(boost::move(x)); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ { return m_tree.insert_unique(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, const value_type& x)
+ { return m_tree.insert_unique(position, x); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_unique(position, boost::move(x)); }
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_unique(position, boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(iterator position, const nonconst_value_type& x)
+ { return m_tree.insert_unique(position, x); }
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(iterator position, BOOST_RV_REF(value_type) x)
+ { return m_tree.insert_unique(position, boost::move(x)); }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with an equivalent key.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_unique(boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with an equivalent key.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator position)
+ { return m_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const map<K1, T1, C1, A1>&,
+ const map<K1, T1, C1, A1>&);
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const map<K1, T1, C1, A1>&,
+ const map<K1, T1, C1, A1>&);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y)
+ { return x.m_tree == y.m_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y)
+ { return x.m_tree < y.m_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator!=(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y)
+ { return !(x == y); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y)
+ { return y < x; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<=(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y)
+ { return !(y < x); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>=(const map<Key,T,Pred,A>& x,
+ const map<Key,T,Pred,A>& y)
+ { return !(x < y); }
+
+template <class Key, class T, class Pred, class A>
+inline void swap(map<Key,T,Pred,A>& x, map<Key,T,Pred,A>& y)
+ { x.swap(y); }
+
+/// @cond
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y);
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y);
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::map<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+//! A multimap is a kind of associative container that supports equivalent keys
+//! (possibly containing multiple copies of the same key value) and provides for
+//! fast retrieval of values of another type T based on the keys. The multimap class
+//! supports bidirectional iterators.
+//!
+//! A multimap satisfies all of the requirements of a container and of a reversible
+//! container and of an associative container. For a
+//! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
+//!
+//! Pred is the ordering function for Keys (e.g. <i>std::less<Key></i>).
+//!
+//! A is the allocator to allocate the value_types
+//!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class Key, class T, class Pred = std::less< std::pair< const Key, T> >, class A = std::allocator<T> >
+#else
+template <class Key, class T, class Pred, class A>
+#endif
+class multimap
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(multimap)
+ typedef containers_detail::rbtree<Key,
+ std::pair<const Key, T>,
+ containers_detail::select1st< std::pair<const Key, T> >,
+ Pred,
+ A> tree_t;
+ tree_t m_tree; // red-black tree representing map
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef T mapped_type;
+ typedef Pred key_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+ typedef std::pair<key_type, mapped_type> nonconst_value_type;
+ typedef containers_detail::pair
+ <key_type, mapped_type> nonconst_impl_value_type;
+
+ /// @cond
+ class value_compare_impl
+ : public Pred,
+ public std::binary_function<value_type, value_type, bool>
+ {
+ friend class multimap<Key,T,Pred,A>;
+ protected :
+ value_compare_impl(const Pred &c) : Pred(c) {}
+ public:
+ bool operator()(const value_type& x, const value_type& y) const {
+ return Pred::operator()(x.first, y.first);
+ }
+ };
+ /// @endcond
+ typedef value_compare_impl value_compare;
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison
+ //! object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit multimap(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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 allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ multimap(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, false)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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
+ //! allocator, and inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : 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)
+ : m_tree(x.m_tree)
+ {
+ //Allocator type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((containers_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>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((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ multimap& operator=(BOOST_RV_REF(multimap) x)
+ { m_tree = boost::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return value_compare(m_tree.key_comp()); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(multimap& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const value_type& x)
+ { return m_tree.insert_equal(x); }
+
+ //! <b>Effects</b>: Inserts a new value constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const nonconst_value_type& x)
+ { return m_tree.insert_equal(x); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(BOOST_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_equal(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
+ //! the iterator pointing to the newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(BOOST_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_equal(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, const value_type& x)
+ { return m_tree.insert_equal(position, x); }
+
+ //! <b>Effects</b>: Inserts a new value constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, const nonconst_value_type& x)
+ { return m_tree.insert_equal(position, x); }
+
+ //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_RV_REF(nonconst_value_type) x)
+ { return m_tree.insert_equal(position, boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(iterator position, BOOST_RV_REF(nonconst_impl_value_type) x)
+ { return m_tree.insert_equal(position, boost::move(x)); }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) .
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_equal(boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by position.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator position)
+ { return m_tree.erase(position); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ {return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator> equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator,const_iterator>
+ equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator== (const multimap<K1, T1, C1, A1>& x,
+ const multimap<K1, T1, C1, A1>& y);
+
+ template <class K1, class T1, class C1, class A1>
+ friend bool operator< (const multimap<K1, T1, C1, A1>& x,
+ const multimap<K1, T1, C1, A1>& y);
+ /// @endcond
+};
+
+template <class Key, class T, class Pred, class A>
+inline bool operator==(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y)
+{ return x.m_tree == y.m_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y)
+{ return x.m_tree < y.m_tree; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator!=(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y)
+{ return !(x == y); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y)
+{ return y < x; }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator<=(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y)
+{ return !(y < x); }
+
+template <class Key, class T, class Pred, class A>
+inline bool operator>=(const multimap<Key,T,Pred,A>& x,
+ const multimap<Key,T,Pred,A>& y)
+{ return !(x < y); }
+
+template <class Key, class T, class Pred, class A>
+inline void swap(multimap<Key,T,Pred,A>& x, multimap<Key,T,Pred,A>& y)
+{ x.swap(y); }
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class K, class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_MAP_HPP */
+
Added: branches/release/boost/container/set.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/set.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1163 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_SET_HPP
+#define BOOST_CONTAINERS_SET_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+
+#include <utility>
+#include <functional>
+#include <memory>
+
+#include <boost/move/move.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/tree.hpp>
+#include <boost/move/move.hpp>
+#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators < and ==, needed for friend declaration.
+template <class T, class Pred, class A>
+inline bool operator==(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y);
+
+template <class T, class Pred, class A>
+inline bool operator<(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y);
+/// @endcond
+
+//! A set is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of the keys themselves.
+//! Class set supports bidirectional iterators.
+//!
+//! A set satisfies all of the requirements of a container and of a reversible container
+//! , and of an associative container. A set also provides most operations described in
+//! for unique keys.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
+#else
+template <class T, class Pred, class A>
+#endif
+class set
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(set)
+ typedef containers_detail::rbtree<T, T,
+ containers_detail::identity<T>, Pred, A> tree_t;
+ tree_t m_tree; // red-black tree representing set
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef Pred key_compare;
+ typedef Pred value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object
+ //! and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit set(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, true)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ set( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a set.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ set(const set& x)
+ : m_tree(x.m_tree)
+ {}
+
+ //! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ set(BOOST_RV_REF(set) x)
+ : m_tree(boost::move(x.m_tree))
+ {}
+
+ //! <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; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ set& operator=(BOOST_RV_REF(set) x)
+ { m_tree = boost::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(set& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ std::pair<iterator,bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
+
+ //! <b>Effects</b>: Move constructs a new value from x if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
+ { return m_tree.insert_unique(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts an element move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+ { return m_tree.insert_unique(p, boost::move(x)); }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) if and only
+ //! if there is no element with key equivalent to the key of that element.
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_unique(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is
+ //! no element in the container with equivalent value.
+ //! and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_unique(boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is
+ //! no element in the container with equivalent value.
+ //! p is a hint pointing to where the insert
+ //! should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by p.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator p)
+ { return m_tree.erase(p); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.find(x) == m_tree.end() ? 0 : 1; }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
+
+ template <class K1, class C1, class A1>
+ friend bool operator< (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
+
+ private:
+ std::pair<iterator, bool> priv_insert(const T &x)
+ { return m_tree.insert_unique(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_tree.insert_unique(p, x); }
+
+ /// @endcond
+};
+
+template <class T, class Pred, class A>
+inline bool operator==(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y)
+{ return x.m_tree == y.m_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator<(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y)
+{ return x.m_tree < y.m_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator!=(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y)
+{ return !(x == y); }
+
+template <class T, class Pred, class A>
+inline bool operator>(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y)
+{ return y < x; }
+
+template <class T, class Pred, class A>
+inline bool operator<=(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y)
+{ return !(y < x); }
+
+template <class T, class Pred, class A>
+inline bool operator>=(const set<T,Pred,A>& x,
+ const set<T,Pred,A>& y)
+{ return !(x < y); }
+
+template <class T, class Pred, class A>
+inline void swap(set<T,Pred,A>& x, set<T,Pred,A>& y)
+{ x.swap(y); }
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::set<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template <class T, class Pred, class A>
+inline bool operator==(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y);
+
+template <class T, class Pred, class A>
+inline bool operator<(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y);
+/// @endcond
+
+//! A multiset is a kind of associative container that supports equivalent keys
+//! (possibly contains multiple copies of the same key value) and provides for
+//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
+//!
+//! A multiset satisfies all of the requirements of a container and of a reversible
+//! container, and of an associative container). multiset also provides most operations
+//! described for duplicate keys.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class Pred = std::less<T>, class A = std::allocator<T> >
+#else
+template <class T, class Pred, class A>
+#endif
+class multiset
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(multiset)
+ typedef containers_detail::rbtree<T, T,
+ containers_detail::identity<T>, Pred, A> tree_t;
+ tree_t m_tree; // red-black tree representing multiset
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
+ /// @endcond
+
+ public:
+
+ // typedefs:
+ typedef typename tree_t::key_type key_type;
+ typedef typename tree_t::value_type value_type;
+ typedef typename tree_t::pointer pointer;
+ typedef typename tree_t::const_pointer const_pointer;
+ typedef typename tree_t::reference reference;
+ typedef typename tree_t::const_reference const_reference;
+ typedef Pred key_compare;
+ typedef Pred value_compare;
+ typedef typename tree_t::iterator iterator;
+ typedef typename tree_t::const_iterator const_iterator;
+ typedef typename tree_t::reverse_iterator reverse_iterator;
+ typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+ typedef typename tree_t::size_type size_type;
+ typedef typename tree_t::difference_type difference_type;
+ typedef typename tree_t::allocator_type allocator_type;
+ typedef typename tree_t::stored_allocator_type stored_allocator_type;
+
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison
+ //! object and allocator.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit multiset(const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(comp, a)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object
+ //! and allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ multiset(InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(first, last, comp, a, false)
+ {}
+
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ multiset( ordered_range_t ordered_range, InputIterator first, InputIterator last
+ , const Pred& comp = Pred()
+ , const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {}
+
+ //! <b>Effects</b>: Copy constructs a multiset.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multiset(const multiset& x)
+ : m_tree(x.m_tree)
+ {}
+
+ //! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
+ //!
+ //! <b>Complexity</b>: Construct.
+ //!
+ //! <b>Postcondition</b>: x is emptied.
+ multiset(BOOST_RV_REF(multiset) x)
+ : m_tree(boost::move(x.m_tree))
+ {}
+
+ //! <b>Effects</b>: Makes *this a copy of x.
+ //!
+ //! <b>Complexity</b>: Linear in x.size().
+ multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
+ { m_tree = x.m_tree; return *this; }
+
+ //! <b>Effects</b>: this->swap(x.get()).
+ //!
+ //! <b>Complexity</b>: Constant.
+ multiset& operator=(BOOST_RV_REF(multiset) x)
+ { m_tree = boost::move(x.m_tree); return *this; }
+
+ //! <b>Effects</b>: Returns the comparison object out
+ //! of which a was constructed.
+ //!
+ //! <b>Complexity</b>: Constant.
+ key_compare key_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns an object of value_compare constructed out
+ //! of the comparison object.
+ //!
+ //! <b>Complexity</b>: Constant.
+ value_compare value_comp() const
+ { return m_tree.key_comp(); }
+
+ //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! was passed to the object's constructor.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return m_tree.get_allocator(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return m_tree.get_stored_allocator(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return m_tree.get_stored_allocator(); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return m_tree.begin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return m_tree.end(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return m_tree.rbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return m_tree.rend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_tree.crend(); }
+
+ //! <b>Effects</b>: Returns true if the container contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return m_tree.empty(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return m_tree.size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return m_tree.max_size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(multiset& x)
+ { m_tree.swap(x.m_tree); }
+
+ //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(BOOST_RV_REF(value_type) x)
+ { return m_tree.insert_equal(boost::move(x)); }
+
+ //! <b>Effects</b>: Inserts a copy of x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
+
+ //! <b>Effects</b>: Inserts a value move constructed from x in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+ { return m_tree.insert_equal(p, boost::move(x)); }
+
+ //! <b>Requires</b>: first, last are not iterators into *this.
+ //!
+ //! <b>Effects</b>: inserts each element from the range [first,last) .
+ //!
+ //! <b>Complexity</b>: At most N log(size()+N) (N is the distance from first to last)
+ template <class InputIterator>
+ void insert(InputIterator first, InputIterator last)
+ { m_tree.insert_equal(first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_equal(boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)...
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element pointed to by p.
+ //!
+ //! <b>Returns</b>: Returns an iterator pointing to the element immediately
+ //! following q prior to the element being erased. If no such element exists,
+ //! returns end().
+ //!
+ //! <b>Complexity</b>: Amortized constant time
+ iterator erase(const_iterator p)
+ { return m_tree.erase(p); }
+
+ //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
+ //!
+ //! <b>Returns</b>: Returns the number of erased elements.
+ //!
+ //! <b>Complexity</b>: log(size()) + count(k)
+ size_type erase(const key_type& x)
+ { return m_tree.erase(x); }
+
+ //! <b>Effects</b>: Erases all the elements in the range [first, last).
+ //!
+ //! <b>Returns</b>: Returns last.
+ //!
+ //! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
+ iterator erase(const_iterator first, const_iterator last)
+ { return m_tree.erase(first, last); }
+
+ //! <b>Effects</b>: erase(a.begin(),a.end()).
+ //!
+ //! <b>Postcondition</b>: size() == 0.
+ //!
+ //! <b>Complexity</b>: linear in size().
+ void clear()
+ { m_tree.clear(); }
+
+ //! <b>Returns</b>: An iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ iterator find(const key_type& x)
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to an element with the key
+ //! equivalent to x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ const_iterator find(const key_type& x) const
+ { return m_tree.find(x); }
+
+ //! <b>Returns</b>: The number of elements with key equivalent to x.
+ //!
+ //! <b>Complexity</b>: log(size())+count(k)
+ size_type count(const key_type& x) const
+ { return m_tree.count(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator lower_bound(const key_type& x)
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than k, or a.end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator lower_bound(const key_type& x) const
+ { return m_tree.lower_bound(x); }
+
+ //! <b>Returns</b>: An iterator pointing to the first element with key not less
+ //! than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ iterator upper_bound(const key_type& x)
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
+ //! less than x, or end() if such an element is not found.
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ const_iterator upper_bound(const key_type& x) const
+ { return m_tree.upper_bound(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<iterator,iterator>
+ equal_range(const key_type& x)
+ { return m_tree.equal_range(x); }
+
+ //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+ //!
+ //! <b>Complexity</b>: Logarithmic
+ std::pair<const_iterator, const_iterator>
+ equal_range(const key_type& x) const
+ { return m_tree.equal_range(x); }
+
+ /// @cond
+ template <class K1, class C1, class A1>
+ friend bool operator== (const multiset<K1,C1,A1>&,
+ const multiset<K1,C1,A1>&);
+ template <class K1, class C1, class A1>
+ friend bool operator< (const multiset<K1,C1,A1>&,
+ const multiset<K1,C1,A1>&);
+ private:
+ iterator priv_insert(const T &x)
+ { return m_tree.insert_equal(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_tree.insert_equal(p, x); }
+
+ /// @endcond
+};
+
+template <class T, class Pred, class A>
+inline bool operator==(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y)
+{ return x.m_tree == y.m_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator<(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y)
+{ return x.m_tree < y.m_tree; }
+
+template <class T, class Pred, class A>
+inline bool operator!=(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y)
+{ return !(x == y); }
+
+template <class T, class Pred, class A>
+inline bool operator>(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y)
+{ return y < x; }
+
+template <class T, class Pred, class A>
+inline bool operator<=(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y)
+{ return !(y < x); }
+
+template <class T, class Pred, class A>
+inline bool operator>=(const multiset<T,Pred,A>& x,
+ const multiset<T,Pred,A>& y)
+{ return !(x < y); }
+
+template <class T, class Pred, class A>
+inline void swap(multiset<T,Pred,A>& x, multiset<T,Pred,A>& y)
+{ x.swap(y); }
+
+/// @cond
+
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class C, class A>
+struct has_trivial_destructor_after_move<boost::container::multiset<T, C, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_SET_HPP */
+
Added: branches/release/boost/container/slist.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/slist.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1536 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_SLIST_HPP
+#define BOOST_CONTAINERS_SLIST_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/container_fwd.hpp>
+#include <boost/move/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/intrusive/slist.hpp>
+
+
+#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+//Preprocessor library to emulate perfect forwarding
+#else
+#include <boost/container/detail/preprocessor.hpp>
+#endif
+
+#include <stdexcept>
+#include <iterator>
+#include <utility>
+#include <memory>
+#include <functional>
+#include <algorithm>
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+
+namespace containers_detail {
+
+template<class VoidPointer>
+struct slist_hook
+{
+ typedef typename containers_detail::bi::make_slist_base_hook
+ <containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
+};
+
+template <class T, class VoidPointer>
+struct slist_node
+ : public slist_hook<VoidPointer>::type
+{
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ slist_node()
+ : m_data()
+ {}
+
+ template<class ...Args>
+ slist_node(Args &&...args)
+ : m_data(boost::forward<Args>(args)...)
+ {}
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ slist_node()
+ : m_data()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif//#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ T m_data;
+};
+
+template<class A>
+struct intrusive_slist_type
+{
+ typedef typename A::value_type value_type;
+ typedef typename boost::pointer_to_other
+ <typename A::pointer, void>::type void_pointer;
+ typedef typename containers_detail::slist_node
+ <value_type, void_pointer> node_type;
+
+ typedef typename containers_detail::bi::make_slist
+ <node_type
+ ,containers_detail::bi::base_hook<typename slist_hook<void_pointer>::type>
+ ,containers_detail::bi::constant_time_size<true>
+ ,containers_detail::bi::size_type<typename A::size_type>
+ >::type container_type;
+ typedef container_type type ;
+};
+
+} //namespace containers_detail {
+
+/// @endcond
+
+//! An slist is a singly linked list: a list where each element is linked to the next
+//! element, but not to the previous element. That is, it is a Sequence that
+//! supports forward but not backward traversal, and (amortized) constant time
+//! insertion and removal of elements. Slists, like lists, have the important
+//! property that insertion and splicing do not invalidate iterators to list elements,
+//! and that even removal invalidates only the iterators that point to the elements
+//! that are removed. The ordering of iterators may be changed (that is,
+//! slist<T>::iterator might have a different predecessor or successor after a list
+//! operation than it did before), but the iterators themselves will not be invalidated
+//! or made to point to different elements unless that invalidation or mutation is explicit.
+//!
+//! The main difference between slist and list is that list's iterators are bidirectional
+//! iterators, while slist's iterators are forward iterators. This means that slist is
+//! less versatile than list; frequently, however, bidirectional iterators are
+//! unnecessary. You should usually use slist unless you actually need the extra
+//! functionality of list, because singly linked lists are smaller and faster than double
+//! linked lists.
+//!
+//! Important performance note: like every other Sequence, slist defines the member
+//! functions insert and erase. Using these member functions carelessly, however, can
+//! result in disastrously slow programs. The problem is that insert's first argument is
+//! an iterator p, and that it inserts the new element(s) before p. This means that
+//! insert must find the iterator just before p; this is a constant-time operation
+//! for list, since list has bidirectional iterators, but for slist it must find that
+//! iterator by traversing the list from the beginning up to p. In other words:
+//! insert and erase are slow operations anywhere but near the beginning of the slist.
+//!
+//! Slist provides the member functions insert_after and erase_after, which are constant
+//! time operations: you should always use insert_after and erase_after whenever
+//! possible. If you find that insert_after and erase_after aren't adequate for your
+//! needs, and that you often need to use insert and erase in the middle of the list,
+//! then you should probably use list instead of slist.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class A = std::allocator<T> >
+#else
+template <class T, class A>
+#endif
+class slist
+ : protected containers_detail::node_alloc_holder
+ <A, typename containers_detail::intrusive_slist_type<A>::type>
+{
+ /// @cond
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
+ typedef typename
+ containers_detail::intrusive_slist_type<A>::type Icont;
+ typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef slist <T, A> ThisType;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::allocator_v1 allocator_v1;
+ typedef typename AllocHolder::allocator_v2 allocator_v2;
+ typedef typename AllocHolder::alloc_version alloc_version;
+
+ class equal_to_value
+ {
+ typedef typename AllocHolder::value_type value_type;
+ const value_type &t_;
+
+ public:
+ equal_to_value(const value_type &t)
+ : t_(t)
+ {}
+
+ bool operator()(const value_type &t)const
+ { return t_ == t; }
+ };
+
+ template<class Pred>
+ struct ValueCompareToNodeCompare
+ : Pred
+ {
+ ValueCompareToNodeCompare(Pred pred)
+ : Pred(pred)
+ {}
+
+ bool operator()(const Node &a, const Node &b) const
+ { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
+
+ bool operator()(const Node &a) const
+ { return static_cast<const Pred&>(*this)(a.m_data); }
+ };
+ /// @endcond
+ public:
+ //! The type of object, T, stored in the list
+ typedef T value_type;
+ //! Pointer to T
+ typedef typename A::pointer pointer;
+ //! Const pointer to T
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to T
+ typedef typename A::reference reference;
+ //! Const reference to T
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! The allocator type
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef NodeAlloc stored_allocator_type;
+
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(slist)
+ typedef difference_type list_difference_type;
+ typedef pointer list_pointer;
+ typedef const_pointer list_const_pointer;
+ typedef reference list_reference;
+ typedef const_reference list_const_reference;
+ /// @endcond
+
+ public:
+
+ //! Const iterator used to iterate through a list.
+ class const_iterator
+ /// @cond
+ : public std::iterator<std::forward_iterator_tag,
+ value_type, list_difference_type,
+ list_const_pointer, list_const_reference>
+ {
+
+ protected:
+ typename Icont::iterator m_it;
+ explicit const_iterator(typename Icont::iterator it) : m_it(it){}
+ void prot_incr(){ ++m_it; }
+
+ private:
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class slist<T, A>;
+ typedef list_difference_type difference_type;
+
+ //Constructors
+ const_iterator()
+ : m_it()
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return m_it->m_data; }
+
+ const_pointer operator->() const
+ { return const_pointer(&m_it->m_data); }
+
+ //Increment / Decrement
+ const_iterator& operator++()
+ { prot_incr(); return *this; }
+
+ const_iterator operator++(int)
+ { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
+
+ //Comparison operators
+ bool operator== (const const_iterator& r) const
+ { return m_it == r.m_it; }
+
+ bool operator!= (const const_iterator& r) const
+ { return m_it != r.m_it; }
+ }
+ /// @endcond
+ ;
+
+ //! Iterator used to iterate through a list
+ class iterator
+ /// @cond
+ : public const_iterator
+ {
+
+ private:
+ explicit iterator(typename Icont::iterator it)
+ : const_iterator(it)
+ {}
+
+ typename Icont::iterator get()
+ { return this->m_it; }
+
+ public:
+ friend class slist<T, A>;
+ typedef list_pointer pointer;
+ typedef list_reference reference;
+
+ //Constructors
+ iterator(){}
+
+ //Pointer like operators
+ reference operator*() const { return this->m_it->m_data; }
+ pointer operator->() const { return pointer(&this->m_it->m_data); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->prot_incr(); return *this; }
+
+ iterator operator++(int)
+ { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
+ }
+ /// @endcond
+ ;
+
+ public:
+ //! <b>Effects</b>: Constructs a list taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit slist(const allocator_type& a = allocator_type())
+ : AllocHolder(a)
+ {}
+
+ explicit slist(size_type n)
+ : AllocHolder(allocator_type())
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
+ : AllocHolder(a)
+ { this->priv_create_and_insert_nodes(this->before_begin(), n, x); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the list.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InpIt>
+ slist(InpIt first, InpIt last,
+ const allocator_type& a = allocator_type())
+ : AllocHolder(a)
+ { this->insert_after(this->before_begin(), first, last); }
+
+ //! <b>Effects</b>: Copy constructs a list.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ slist(const slist& x)
+ : AllocHolder(x)
+ { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ slist(BOOST_RV_REF(slist) x)
+ : AllocHolder(boost::move((AllocHolder&)x))
+ {}
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x)
+ {
+ if (&x != this){
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ slist& operator= (BOOST_RV_REF(slist) mx)
+ {
+ if (&mx != this){
+ this->clear();
+ this->swap(mx);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~slist()
+ {} //AllocHolder clears the slist
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ public:
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
+
+ //! <b>Effects</b>: Assigns the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InpIt>
+ void assign(InpIt first, InpIt last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return iterator(this->icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return iterator(this->icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->cend(); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
+ //! when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator before_begin()
+ { return iterator(end()); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+ //! that, when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator before_begin() const
+ { return this->cbefore_begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+ //! that, when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbefore_begin() const
+ { return const_iterator(end()); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->icont().size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return AllocHolder::max_size(); }
+
+ //! <b>Effects</b>: Returns true if the list contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->size(); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements on *this and x.
+ void swap(slist& x)
+ { AllocHolder::swap(x); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return *this->begin(); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->begin(); }
+
+ //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(insert_const_ref_type x)
+ { return priv_push_front(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ void push_front(T &x) { push_front(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_front(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_push_front(u); }
+ #endif
+
+ //! <b>Effects</b>: Constructs a new element in the beginning of the list
+ //! and moves the resources of t to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(BOOST_RV_REF(T) x)
+ { this->icont().push_front(*this->create_node(boost::move(x))); }
+
+ //! <b>Effects</b>: Removes the first element from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void pop_front()
+ { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
+
+ //! <b>Returns</b>: The iterator to the element before i in the sequence.
+ //! Returns the end-iterator, if either i is the begin-iterator or the
+ //! sequence is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ iterator previous(iterator p)
+ { return iterator(this->icont().previous(p.get())); }
+
+ //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
+ //! Returns the end-const_iterator, if either i is the begin-const_iterator or
+ //! the sequence is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ const_iterator previous(const_iterator p)
+ { return const_iterator(this->icont().previous(p.get())); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts a copy of the value after the p pointed
+ //! by prev_p.
+ //!
+ //! <b>Returns</b>: An iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ iterator insert_after(const_iterator prev_pos, insert_const_ref_type x)
+ { return this->priv_insert_after(prev_pos, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert_after(const_iterator position, T &x)
+ { return this->insert_after(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert_after(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return this->priv_insert_after(position, u); }
+ #endif
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts a move constructed copy object from the value after the
+ //! p pointed by prev_pos.
+ //!
+ //! <b>Returns</b>: An iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ iterator insert_after(const_iterator prev_pos, BOOST_RV_REF(value_type) x)
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(boost::move(x)))); }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x after prev_pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
+ { this->priv_create_and_insert_nodes(prev_pos, n, x); }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts the range pointed by [first, last)
+ //! after the p prev_pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements inserted.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references of
+ //! previous values.
+ template <class InIter>
+ void insert_after(const_iterator prev_pos, InIter first, InIter last)
+ {
+ const bool aux_boolean = containers_detail::is_convertible<InIter, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p.
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p.
+ iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
+ { return this->insert_after(previous(p), boost::move(x)); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
+ void insert(const_iterator p, size_type n, const value_type& x)
+ { return this->insert_after(previous(p), n, x); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last) plus
+ //! linear to the elements before p.
+ template <class InIter>
+ void insert(const_iterator p, InIter first, InIter last)
+ { return this->insert_after(previous(p), first, last); }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the front of the list
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ { this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ { return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... after prev
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace_after(const_iterator prev, Args&&... args)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node(boost::forward<Args>(args)...);
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert_after(prev.get(), *node));
+ }
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_front()
+ { this->emplace_after(this->cbefore_begin()); }
+
+ iterator emplace(const_iterator p)
+ { return this->emplace_after(this->previous(p)); }
+
+ iterator emplace_after(const_iterator prev)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)containers_detail::get_pointer(d.get())) Node();
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert_after(prev.get(), *node));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace \
+ (this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace \
+ (const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_after \
+ (this->previous(p), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_after \
+ (const_iterator prev, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
+ new ((void*)containers_detail::get_pointer(d.get())) \
+ Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ NodePtr node = d.get(); \
+ d.release(); \
+ return iterator(this->icont().insert_after(prev.get(), *node)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element after the element pointed by prev_pos
+ //! of the list.
+ //!
+ //! <b>Returns</b>: the first element remaining beyond the removed elements,
+ //! or end() if no such element exists.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
+ iterator erase_after(const_iterator prev_pos)
+ {
+ return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
+ }
+
+ //! <b>Effects</b>: Erases the range (before_first, last) from
+ //! the list.
+ //!
+ //! <b>Returns</b>: the first element remaining beyond the removed elements,
+ //! or end() if no such element exists.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of erased elements.
+ //!
+ //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
+ iterator erase_after(const_iterator before_first, const_iterator last)
+ {
+ return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Erases the element at p p.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before p.
+ iterator erase(const_iterator p)
+ { return iterator(this->erase_after(previous(p))); }
+
+ //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+ //!
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last plus
+ //! linear to the elements before first.
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(this->erase_after(previous(first), last)); }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+ while (++(cur_next = cur) != end_n && new_size > 0){
+ --new_size;
+ cur = cur_next;
+ }
+ if (cur_next != end_n)
+ this->erase_after(const_iterator(cur), const_iterator(end_n));
+ else
+ this->insert_after(const_iterator(cur), new_size, x);
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+ size_type len = this->size();
+ size_type left = new_size;
+
+ while (++(cur_next = cur) != end_n && left > 0){
+ --left;
+ cur = cur_next;
+ }
+ if (cur_next != end_n){
+ this->erase_after(const_iterator(cur), const_iterator(end_n));
+ }
+ else{
+ this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
+ }
+ }
+
+ //! <b>Effects</b>: Erases all the elements of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the list.
+ void clear()
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the elements in x.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after(prev_pos.get(), x.icont());
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! after the element pointed by prev_pos.
+ //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
+ //!
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the number of transferred elements.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
+ //! n == std::distance(before_first, before_last)
+ //!
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last,
+ size_type n)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
+ }
+ else{
+ throw std::runtime_error("slist::splice called with unequal allocators");
+ }
+ }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, ThisType& x)
+ { this->splice_after(this->previous(p), x); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x, const_iterator i)
+ { this->splice_after(previous(p), x, i); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
+ //! and in distance(first, last).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+ { this->splice_after(previous(p), x, previous(first), previous(last)); }
+
+ //! <b>Effects</b>: Reverses the order of elements in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time.
+ //!
+ //! <b>Note</b>: Iterators and references are not invalidated
+ void reverse()
+ { this->icont().reverse(); }
+
+ //! <b>Effects</b>: Removes all the elements that compare equal to value.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void remove(const T& value)
+ { remove_if(equal_to_value(value)); }
+
+ //! <b>Effects</b>: Removes all the elements for which a specified
+ //! predicate is satisfied.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time. It performs exactly size() calls to the predicate.
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class Pred>
+ void remove_if(Pred pred)
+ {
+ typedef ValueCompareToNodeCompare<Pred> Predicate;
+ this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that are equal from the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ void unique()
+ { this->unique(value_equal()); }
+
+ //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
+ //! elements that satisfy some binary predicate from the list.
+ //!
+ //! <b>Throws</b>: If pred throws.
+ //!
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //!
+ //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
+ //! and iterators to elements that are not removed remain valid.
+ template <class Pred>
+ void unique(Pred pred)
+ {
+ typedef ValueCompareToNodeCompare<Pred> Predicate;
+ this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
+ }
+
+ //! <b>Requires</b>: The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this according to std::less<value_type>. The merge is stable;
+ //! that is, if an element from *this is equivalent to one from x, then the element
+ //! from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ void merge(slist & x)
+ { this->merge(x, value_less()); }
+
+ //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+ //! ordering and both *this and x must be sorted according to that ordering
+ //! The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this. The merge is stable; that is, if an element from *this is
+ //! equivalent to one from x, then the element from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ //!
+ //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ template <class StrictWeakOrdering>
+ void merge(slist& x, StrictWeakOrdering comp)
+ {
+ if((NodeAlloc&)*this == (NodeAlloc&)x){
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+ else{
+ throw std::runtime_error("list::merge called with unequal allocators");
+ }
+ }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ void sort()
+ { this->sort(value_less()); }
+
+ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
+ //! The sort is stable, that is, the relative order of equivalent elements is preserved.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
+ //! is the list's size.
+ template <class StrictWeakOrdering>
+ void sort(StrictWeakOrdering comp)
+ {
+ // nothing if the slist has length 0 or 1.
+ if (this->size() < 2)
+ return;
+ this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ }
+
+ /// @cond
+ private:
+ iterator priv_insert(const_iterator p, const value_type& x)
+ { return this->insert_after(previous(p), x); }
+
+ iterator priv_insert_after(const_iterator prev_pos, const value_type& x)
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
+
+ void priv_push_front(const value_type &x)
+ { this->icont().push_front(*this->create_node(x)); }
+
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, InpIterator beg, InpIterator end)
+ {
+ typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
+ priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat());
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+ {
+ for (; beg != end; ++beg){
+ this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
+ ++prev;
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+ typename Icont::const_iterator prev_;
+
+ public:
+ insertion_functor(Icont &icont, typename Icont::const_iterator prev)
+ : icont_(icont), prev_(prev)
+ {}
+
+ void operator()(Node &n)
+ { prev_ = this->icont_.insert_after(prev_, n); }
+ };
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
+ }
+
+ //Default constructed version
+ void priv_create_and_insert_nodes(const_iterator prev, size_type n)
+ {
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator());
+ }
+
+ //Copy constructed version
+ void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator());
+ }
+
+ //Dispatch to detect iterator range or integer overloads
+ template <class InputIter>
+ void priv_insert_dispatch(const_iterator prev,
+ InputIter first, InputIter last,
+ containers_detail::false_)
+ { this->priv_create_and_insert_nodes(prev, first, last); }
+
+ template<class Integer>
+ void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, containers_detail::true_)
+ { this->priv_create_and_insert_nodes(prev, (size_type)n, x); }
+
+ void priv_fill_assign(size_type n, const T& val)
+ {
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
+ for ( ; node != end_n && n > 0 ; --n){
+ *node = val;
+ prev = node;
+ ++node;
+ }
+ if (n > 0)
+ this->priv_create_and_insert_nodes(prev, n, val);
+ else
+ this->erase_after(prev, end_n);
+ }
+
+ template <class Int>
+ void priv_assign_dispatch(Int n, Int val, containers_detail::true_)
+ { this->priv_fill_assign((size_type) n, (T)val); }
+
+ template <class InpIt>
+ void priv_assign_dispatch(InpIt first, InpIt last, containers_detail::false_)
+ {
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
+ while (node != end_n && first != last){
+ *node = *first;
+ prev = node;
+ ++node;
+ ++first;
+ }
+ if (first != last)
+ this->priv_create_and_insert_nodes(prev, first, last);
+ else
+ this->erase_after(prev, end_n);
+ }
+
+ template <class Int>
+ void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, containers_detail::true_)
+ { this->priv_create_and_insert_nodes(prev_pos, (size_type)n, x); }
+
+ template <class InIter>
+ void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, containers_detail::false_)
+ { this->priv_create_and_insert_nodes(prev_pos, first, last); }
+
+ //Functors for member algorithm defaults
+ struct value_less
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a < b; }
+ };
+
+ struct value_equal
+ {
+ bool operator()(const value_type &a, const value_type &b) const
+ { return a == b; }
+ };
+
+ struct value_equal_to_this
+ {
+ explicit value_equal_to_this(const value_type &ref)
+ : m_ref(ref){}
+
+ bool operator()(const value_type &val) const
+ { return m_ref == val; }
+
+ const value_type &m_ref;
+ };
+ /// @endcond
+};
+
+template <class T, class A>
+inline bool
+operator==(const slist<T,A>& x, const slist<T,A>& y)
+{
+ if(x.size() != y.size()){
+ return false;
+ }
+ typedef typename slist<T,A>::const_iterator const_iterator;
+ const_iterator end1 = x.end();
+
+ const_iterator i1 = x.begin();
+ const_iterator i2 = y.begin();
+ while (i1 != end1 && *i1 == *i2){
+ ++i1;
+ ++i2;
+ }
+ return i1 == end1;
+}
+
+template <class T, class A>
+inline bool
+operator<(const slist<T,A>& sL1, const slist<T,A>& sL2)
+{
+ return std::lexicographical_compare
+ (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
+}
+
+template <class T, class A>
+inline bool
+operator!=(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return !(sL1 == sL2); }
+
+template <class T, class A>
+inline bool
+operator>(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return sL2 < sL1; }
+
+template <class T, class A>
+inline bool
+operator<=(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return !(sL2 < sL1); }
+
+template <class T, class A>
+inline bool
+operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2)
+ { return !(sL1 < sL2); }
+
+template <class T, class A>
+inline void swap(slist<T,A>& x, slist<T,A>& y)
+ { x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::container::slist<T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}} //namespace boost{ namespace container {
+
+// Specialization of insert_iterator so that insertions will be constant
+// time rather than linear time.
+
+///@cond
+
+//Ummm, I don't like to define things in namespace std, but
+//there is no other way
+namespace std {
+
+template <class T, class A>
+class insert_iterator<boost::container::slist<T, A> >
+{
+ protected:
+ typedef boost::container::slist<T, A> Container;
+ Container* container;
+ typename Container::iterator iter;
+ public:
+ typedef Container container_type;
+ typedef output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef void difference_type;
+ typedef void pointer;
+ typedef void reference;
+
+ insert_iterator(Container& x,
+ typename Container::iterator i,
+ bool is_previous = false)
+ : container(&x), iter(is_previous ? i : x.previous(i)){ }
+
+ insert_iterator<Container>&
+ operator=(const typename Container::value_type& value)
+ {
+ iter = container->insert_after(iter, value);
+ return *this;
+ }
+ insert_iterator<Container>& operator*(){ return *this; }
+ insert_iterator<Container>& operator++(){ return *this; }
+ insert_iterator<Container>& operator++(int){ return *this; }
+};
+
+} //namespace std;
+
+///@endcond
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif /* BOOST_CONTAINERS_SLIST_HPP */
Added: branches/release/boost/container/stable_vector.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/stable_vector.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,1701 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+/* Stable vector.
+ *
+ * Copyright 2008 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
+#define BOOST_CONTAINER_STABLE_VECTOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/algorithms.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/get_pointer.hpp>
+
+#include <algorithm>
+#include <stdexcept>
+#include <memory>
+
+///@cond
+
+#include <boost/container/vector.hpp>
+
+//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+
+#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+#include <boost/assert.hpp>
+#endif
+
+///@endcond
+
+namespace boost {
+namespace container {
+
+///@cond
+
+namespace stable_vector_detail{
+
+template<class SmartPtr>
+struct smart_ptr_type
+{
+ typedef typename SmartPtr::value_type value_type;
+ typedef value_type *pointer;
+ static pointer get (const SmartPtr &smartptr)
+ { return smartptr.get();}
+};
+
+template<class T>
+struct smart_ptr_type<T*>
+{
+ typedef T value_type;
+ typedef value_type *pointer;
+ static pointer get (pointer ptr)
+ { return ptr;}
+};
+
+template<class Ptr>
+inline typename smart_ptr_type<Ptr>::pointer get_pointer(const Ptr &ptr)
+{ return smart_ptr_type<Ptr>::get(ptr); }
+
+template <class C>
+class clear_on_destroy
+{
+ public:
+ clear_on_destroy(C &c)
+ : c_(c), do_clear_(true)
+ {}
+
+ void release()
+ { do_clear_ = false; }
+
+ ~clear_on_destroy()
+ {
+ if(do_clear_){
+ c_.clear();
+ c_.clear_pool();
+ }
+ }
+
+ private:
+ clear_on_destroy(const clear_on_destroy &);
+ clear_on_destroy &operator=(const clear_on_destroy &);
+ C &c_;
+ bool do_clear_;
+};
+
+template<class VoidPtr>
+struct node_type_base
+{/*
+ node_type_base(VoidPtr p)
+ : up(p)
+ {}*/
+ node_type_base()
+ {}
+ void set_pointer(VoidPtr p)
+ { up = p; }
+
+ VoidPtr up;
+};
+
+template<typename VoidPointer, typename T>
+struct node_type
+ : public node_type_base<VoidPointer>
+{
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ node_type()
+ : value()
+ {}
+
+ template<class ...Args>
+ node_type(Args &&...args)
+ : value(boost::forward<Args>(args)...)
+ {}
+
+ #else //BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ node_type()
+ : value()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ node_type(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ : value(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif//BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ void set_pointer(VoidPointer p)
+ { node_type_base<VoidPointer>::set_pointer(p); }
+
+ T value;
+};
+
+template<typename T, typename Reference, typename Pointer>
+class iterator
+ : public std::iterator< std::random_access_iterator_tag
+ , typename std::iterator_traits<Pointer>::value_type
+ , typename std::iterator_traits<Pointer>::difference_type
+ , Pointer
+ , Reference>
+{
+
+ typedef typename boost::pointer_to_other
+ <Pointer, void>::type void_ptr;
+ typedef typename boost::pointer_to_other
+ <Pointer, const void>::type const_void_ptr;
+ typedef node_type<void_ptr, T> node_type_t;
+ typedef typename boost::pointer_to_other
+ <void_ptr, node_type_t>::type node_type_ptr_t;
+ typedef typename boost::pointer_to_other
+ <void_ptr, const node_type_t>::type const_node_type_ptr_t;
+ typedef typename boost::pointer_to_other
+ <void_ptr, void_ptr>::type void_ptr_ptr;
+
+ friend class iterator<T, const T, typename boost::pointer_to_other<Pointer, T>::type>;
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef typename std::iterator_traits
+ <Pointer>::difference_type difference_type;
+ typedef Pointer pointer;
+ typedef Reference reference;
+
+ iterator()
+ {}
+
+ explicit iterator(node_type_ptr_t pn)
+ : pn(pn)
+ {}
+
+ iterator(const iterator<T, T&, typename boost::pointer_to_other<Pointer, T>::type >& x)
+ : pn(x.pn)
+ {}
+
+ private:
+ static node_type_ptr_t node_ptr_cast(const void_ptr &p)
+ {
+ using boost::get_pointer;
+ return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
+ {
+ using boost::get_pointer;
+ return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
+ {
+ using boost::get_pointer;
+ return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ reference dereference() const
+ { return pn->value; }
+ bool equal(const iterator& x) const
+ { return pn==x.pn; }
+ void increment()
+ { pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+1)); }
+ void decrement()
+ { pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)-1)); }
+ void advance(difference_type n)
+ { pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+n)); }
+ difference_type distance_to(const iterator& x)const
+ { return void_ptr_ptr_cast(x.pn->up) - void_ptr_ptr_cast(pn->up); }
+
+ public:
+ //Pointer like operators
+ reference operator*() const { return this->dereference(); }
+ pointer operator->() const { return pointer(&this->dereference()); }
+
+ //Increment / Decrement
+ iterator& operator++()
+ { this->increment(); return *this; }
+
+ iterator operator++(int)
+ { iterator tmp(*this); ++*this; return iterator(tmp); }
+
+ iterator& operator--()
+ { this->decrement(); return *this; }
+
+ iterator operator--(int)
+ { iterator tmp(*this); --*this; return iterator(tmp); }
+
+ reference operator[](difference_type off) const
+ {
+ iterator tmp(*this);
+ tmp += off;
+ return *tmp;
+ }
+
+ iterator& operator+=(difference_type off)
+ {
+ pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+off));
+ return *this;
+ }
+
+ friend iterator operator+(const iterator &left, difference_type off)
+ {
+ iterator tmp(left);
+ tmp += off;
+ return tmp;
+ }
+
+ friend iterator operator+(difference_type off, const iterator& right)
+ {
+ iterator tmp(right);
+ tmp += off;
+ return tmp;
+ }
+
+ iterator& operator-=(difference_type off)
+ { *this += -off; return *this; }
+
+ friend iterator operator-(const iterator &left, difference_type off)
+ {
+ iterator tmp(left);
+ tmp -= off;
+ return tmp;
+ }
+
+ friend difference_type operator-(const iterator& left, const iterator& right)
+ {
+ return void_ptr_ptr_cast(left.pn->up) - void_ptr_ptr_cast(right.pn->up);
+ }
+
+ //Comparison operators
+ friend bool operator== (const iterator& l, const iterator& r)
+ { return l.pn == r.pn; }
+
+ friend bool operator!= (const iterator& l, const iterator& r)
+ { return l.pn != r.pn; }
+
+ friend bool operator< (const iterator& l, const iterator& r)
+ { return void_ptr_ptr_cast(l.pn->up) < void_ptr_ptr_cast(r.pn->up); }
+
+ friend bool operator<= (const iterator& l, const iterator& r)
+ { return void_ptr_ptr_cast(l.pn->up) <= void_ptr_ptr_cast(r.pn->up); }
+
+ friend bool operator> (const iterator& l, const iterator& r)
+ { return void_ptr_ptr_cast(l.pn->up) > void_ptr_ptr_cast(r.pn->up); }
+
+ friend bool operator>= (const iterator& l, const iterator& r)
+ { return void_ptr_ptr_cast(l.pn->up) >= void_ptr_ptr_cast(r.pn->up); }
+
+ node_type_ptr_t pn;
+};
+
+template<class A, unsigned int Version>
+struct select_multiallocation_chain
+{
+ typedef typename A::multiallocation_chain type;
+};
+
+template<class A>
+struct select_multiallocation_chain<A, 1>
+{
+ typedef typename A::template
+ rebind<void>::other::pointer void_ptr;
+ typedef containers_detail::basic_multiallocation_chain
+ <void_ptr> multialloc_cached_counted;
+ typedef boost::container::containers_detail::transform_multiallocation_chain
+ <multialloc_cached_counted, typename A::value_type> type;
+};
+
+} //namespace stable_vector_detail
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+#define STABLE_VECTOR_CHECK_INVARIANT \
+invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
+BOOST_JOIN(check_invariant_,__LINE__).touch();
+#else
+
+#define STABLE_VECTOR_CHECK_INVARIANT
+
+#endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+#endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+/// @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.
+//!
+//!More details taken the author's blog: ( Introducing stable_vector)
+//!
+//!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.
+//!
+//!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:
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class A = std::allocator<T> >
+#else
+template <class T, class A>
+#endif
+class stable_vector
+{
+ ///@cond
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
+ typedef typename A::template
+ rebind<void>::other::pointer void_ptr;
+ typedef typename boost::pointer_to_other
+ <void_ptr, const void>::type const_void_ptr;
+ typedef typename A::template
+ rebind<void_ptr>::other::pointer void_ptr_ptr;
+ typedef typename boost::pointer_to_other
+ <void_ptr, const void_ptr>::type const_void_ptr_ptr;
+ typedef stable_vector_detail::node_type
+ <void_ptr, T> node_type_t;
+ typedef typename A::template
+ rebind<node_type_t>::other::pointer node_type_ptr_t;
+ typedef stable_vector_detail::node_type_base
+ <void_ptr> node_type_base_t;
+ typedef typename A::template
+ rebind<node_type_base_t>::other::pointer node_type_base_ptr_t;
+ typedef
+ ::boost::container::vector<void_ptr,
+ typename A::
+ template rebind<void_ptr>::other
+ > impl_type;
+ typedef typename impl_type::iterator impl_iterator;
+ typedef typename impl_type::const_iterator const_impl_iterator;
+
+ typedef ::boost::container::containers_detail::
+ integral_constant<unsigned, 1> allocator_v1;
+ typedef ::boost::container::containers_detail::
+ integral_constant<unsigned, 2> allocator_v2;
+ typedef ::boost::container::containers_detail::integral_constant
+ <unsigned, boost::container::containers_detail::
+ version<A>::value> alloc_version;
+ typedef typename A::
+ template rebind<node_type_t>::other node_allocator_type;
+
+ node_type_ptr_t allocate_one()
+ { return this->allocate_one(alloc_version()); }
+
+ node_type_ptr_t allocate_one(allocator_v1)
+ { return get_al().allocate(1); }
+
+ node_type_ptr_t allocate_one(allocator_v2)
+ { return get_al().allocate_one(); }
+
+ void deallocate_one(node_type_ptr_t p)
+ { return this->deallocate_one(p, alloc_version()); }
+
+ void deallocate_one(node_type_ptr_t p, allocator_v1)
+ { get_al().deallocate(p, 1); }
+
+ void deallocate_one(node_type_ptr_t p, allocator_v2)
+ { get_al().deallocate_one(p); }
+
+ friend class stable_vector_detail::clear_on_destroy<stable_vector>;
+ ///@endcond
+ public:
+
+
+ // types:
+
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef stable_vector_detail::iterator
+ <T,T&, pointer> iterator;
+ typedef stable_vector_detail::iterator
+ <T,const T&, const_pointer> const_iterator;
+ typedef typename impl_type::size_type size_type;
+ typedef typename iterator::difference_type difference_type;
+ typedef T value_type;
+ typedef A allocator_type;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ ///@cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(stable_vector)
+ static const size_type ExtraPointers = 3;
+ //This container stores metadata at the end of the void_ptr vector with additional 3 pointers:
+ // back() is impl.back() - ExtraPointers;
+ // end node index is impl.end()[-3]
+ // Node cache first is impl.end()[-2];
+ // Node cache last is *impl.back();
+
+ typedef typename stable_vector_detail::
+ select_multiallocation_chain
+ < node_allocator_type
+ , alloc_version::value
+ >::type multiallocation_chain;
+ ///@endcond
+ public:
+
+ //! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit stable_vector(const A& al=A())
+ : internal_data(al),impl(al)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ }
+
+ //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! and inserts n default contructed values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit stable_vector(size_type n)
+ : internal_data(A()),impl(A())
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->resize(n);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ stable_vector(size_type n, const T& t, const A& al=A())
+ : internal_data(al),impl(al)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), n, t);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the stable_vector.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InputIterator>
+ stable_vector(InputIterator first,InputIterator last,const A& al=A())
+ : internal_data(al),impl(al)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), first, last);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Copy constructs a stable_vector.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ stable_vector(const stable_vector& x)
+ : internal_data(x.get_al()),impl(x.get_al())
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->insert(this->cbegin(), x.begin(), x.end());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ stable_vector(BOOST_RV_REF(stable_vector) x)
+ : internal_data(x.get_al()),impl(x.get_al())
+ { this->swap(x); }
+
+ //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~stable_vector()
+ {
+ this->clear();
+ clear_pool();
+ }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if (this != &x) {
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear.
+ stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
+ {
+ if (&x != this){
+ this->swap(x);
+ x.clear();
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template<typename InputIterator>
+ void assign(InputIterator first,InputIterator last)
+ {
+ assign_dispatch(first, last, boost::is_integral<InputIterator>());
+ }
+
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n,const T& t)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+ }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator()const {return get_al();}
+
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return (impl.empty()) ? end(): iterator(node_ptr_cast(impl.front())) ; }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin()const
+ { return (impl.empty()) ? cend() : const_iterator(node_ptr_cast(impl.front())) ; }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end() {return iterator(get_end_node());}
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end()const {return const_iterator(get_end_node());}
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin() {return reverse_iterator(this->end());}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin()const {return const_reverse_iterator(this->end());}
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend() {return reverse_iterator(this->begin());}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend()const {return const_reverse_iterator(this->begin());}
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin()const {return this->begin();}
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend()const {return this->end();}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin()const{return this->rbegin();}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend()const {return this->rend();}
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return impl.empty() ? 0 : (impl.size() - ExtraPointers); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return impl.max_size() - ExtraPointers; }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ {
+ if(!impl.capacity()){
+ return 0;
+ }
+ else{
+ const size_type num_nodes = this->impl.size() + this->internal_data.pool_size;
+ const size_type num_buck = this->impl.capacity();
+ return (num_nodes < num_buck) ? num_nodes : num_buck;
+ }
+ }
+
+ //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return impl.empty() || impl.size() == ExtraPointers; }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n, const T& t)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > size())
+ this->insert(this->cend(), n - this->size(), t);
+ else if(n < this->size())
+ this->erase(this->cbegin() + n, this->cend());
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n)
+ {
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > size())
+ this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
+ else if(n < this->size())
+ this->erase(this->cbegin() + n, this->cend());
+ }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws.
+ void reserve(size_type n)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > this->max_size())
+ throw std::bad_alloc();
+
+ size_type size = this->size();
+ size_type old_capacity = this->capacity();
+ if(n > old_capacity){
+ this->initialize_end_node(n);
+ const void * old_ptr = &impl[0];
+ impl.reserve(n + ExtraPointers);
+ bool realloced = &impl[0] != old_ptr;
+ //Fix the pointers for the newly allocated buffer
+ if(realloced){
+ this->align_nodes(impl.begin(), impl.begin()+size+1);
+ }
+ //Now fill pool if data is not enough
+ if((n - size) > this->internal_data.pool_size){
+ this->add_to_pool((n - size) - this->internal_data.pool_size);
+ }
+ }
+ }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n){return value(impl[n]);}
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n)const{return value(impl[n]);}
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n)
+ {
+ if(n>=size())
+ throw std::out_of_range("invalid subscript at stable_vector::at");
+ return operator[](n);
+ }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n)const
+ {
+ if(n>=size())
+ throw std::out_of_range("invalid subscript at stable_vector::at");
+ return operator[](n);
+ }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return value(impl.front()); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front()const
+ { return value(impl.front()); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back()
+ { return value(*(&impl.back() - ExtraPointers)); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back()const
+ { return value(*(&impl.back() - ExtraPointers)); }
+
+ //! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(insert_const_ref_type x)
+ { return priv_push_back(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ void push_back(T &x) { push_back(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return priv_push_back(u); }
+ #endif
+
+ //! <b>Effects</b>: Constructs a new element in the end of the stable_vector
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(BOOST_RV_REF(T) t)
+ { this->insert(end(), boost::move(t)); }
+
+ //! <b>Effects</b>: Removes the last element from the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ void pop_back()
+ { this->erase(this->end()-1); }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before position.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before position with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, BOOST_RV_REF(T) x)
+ {
+ typedef repeat_iterator<T, difference_type> repeat_it;
+ typedef boost::move_iterator<repeat_it> repeat_move_it;
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position
+ ,repeat_move_it(repeat_it(x, 1))
+ ,repeat_move_it(repeat_it()));
+ return iterator(this->begin() + pos_n);
+ }
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert n copies of x before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void insert(const_iterator position, size_type n, const T& t)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ this->insert_not_iter(position, n, t);
+ }
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last).
+ template <class InputIterator>
+ void insert(const_iterator position,InputIterator first, InputIterator last)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ this->insert_iter(position,first,last,
+ boost::mpl::not_<boost::is_integral<InputIterator> >());
+ }
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the stable_vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template<class ...Args>
+ void emplace_back(Args &&...args)
+ {
+ typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template<class ...Args>
+ iterator emplace(const_iterator position, Args && ...args)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
+ this->insert(position, EmplaceIterator(ef), EmplaceIterator());
+ return iterator(this->begin() + pos_n);
+ }
+
+ #else
+
+ void emplace_back()
+ {
+ typedef emplace_functor<node_type_t> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ EmplaceFunctor ef;
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+ }
+
+ iterator emplace(const_iterator position)
+ {
+ typedef emplace_functor<node_type_t> EmplaceFunctor;
+ typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
+ EmplaceFunctor ef;
+ size_type pos_n = position - this->cbegin();
+ this->insert(position, EmplaceIterator(ef), EmplaceIterator());
+ return iterator(this->begin() + pos_n);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ <node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
+ typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
+ EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ <node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
+ typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
+ EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ size_type pos_n = pos - this->cbegin(); \
+ this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
+ return iterator(this->begin() + pos_n); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Erases the element at position pos.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the elements between pos and the
+ //! last element. Constant if pos is the last element.
+ iterator erase(const_iterator position)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ difference_type d = position - this->cbegin();
+ impl_iterator it = impl.begin() + d;
+ this->delete_node(*it);
+ it = impl.erase(it);
+ this->align_nodes(it, get_last_align());
+ return this->begin()+d;
+ }
+
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last
+ //! plus linear to the elements between pos and the last element.
+ iterator erase(const_iterator first, const_iterator last)
+ { return priv_erase(first, last, alloc_version()); }
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(stable_vector & x)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ this->swap_impl(*this,x);
+ }
+
+ //! <b>Effects</b>: Erases all the elements of the stable_vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
+ void clear()
+ { this->erase(this->cbegin(),this->cend()); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the stable_vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ {
+ if(this->capacity()){
+ //First empty allocated node pool
+ this->clear_pool();
+ //If empty completely destroy the index, let's recover default-constructed state
+ if(this->empty()){
+ impl_type().swap(this->impl);
+ this->internal_data.set_end_pointer_to_default_constructed();
+ }
+ //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
+ else{
+ const size_type size = this->size();
+ const void* old_ptr = &impl[0];
+ this->impl.shrink_to_fit();
+ bool realloced = &impl[0] != old_ptr;
+ //Fix the pointers for the newly allocated buffer
+ if(realloced){
+ this->align_nodes(impl.begin(), impl.begin()+size+1);
+ }
+ }
+ }
+ }
+
+ /// @cond
+
+ iterator priv_insert(const_iterator position, const value_type &t)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
+ }
+
+ void priv_push_back(const value_type &t)
+ { this->insert(end(), t); }
+
+ void clear_pool(allocator_v1)
+ {
+ if(!impl.empty() && impl.back()){
+ void_ptr &pool_first_ref = impl.end()[-2];
+ void_ptr &pool_last_ref = impl.back();
+
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, this->internal_data.pool_size);
+ while(!holder.empty()){
+ node_type_ptr_t n = holder.front();
+ holder.pop_front();
+ this->deallocate_one(n);
+ }
+ pool_first_ref = pool_last_ref = 0;
+ this->internal_data.pool_size = 0;
+ }
+ }
+
+ void clear_pool(allocator_v2)
+ {
+
+ if(!impl.empty() && impl.back()){
+ void_ptr &pool_first_ref = impl.end()[-2];
+ void_ptr &pool_last_ref = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+ get_al().deallocate_individual(boost::move(holder));
+ pool_first_ref = pool_last_ref = 0;
+ this->internal_data.pool_size = 0;
+ }
+ }
+
+ void clear_pool()
+ {
+ this->clear_pool(alloc_version());
+ }
+
+ void add_to_pool(size_type n)
+ {
+ this->add_to_pool(n, alloc_version());
+ }
+
+ void add_to_pool(size_type n, allocator_v1)
+ {
+ size_type remaining = n;
+ while(remaining--){
+ this->put_in_pool(this->allocate_one());
+ }
+ }
+
+ void add_to_pool(size_type n, allocator_v2)
+ {
+ void_ptr &pool_first_ref = impl.end()[-2];
+ void_ptr &pool_last_ref = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+ //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<multiallocation_chain>::value == true));
+ multiallocation_chain m (get_al().allocate_individual(n));
+ holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
+ this->internal_data.pool_size += n;
+ std::pair<void_ptr, void_ptr> data(holder.extract_data());
+ pool_first_ref = data.first;
+ pool_last_ref = data.second;
+ }
+
+ void put_in_pool(node_type_ptr_t p)
+ {
+ void_ptr &pool_first_ref = impl.end()[-2];
+ void_ptr &pool_last_ref = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+ holder.push_front(p);
+ ++this->internal_data.pool_size;
+ std::pair<void_ptr, void_ptr> ret(holder.extract_data());
+ pool_first_ref = ret.first;
+ pool_last_ref = ret.second;
+ }
+
+ node_type_ptr_t get_from_pool()
+ {
+ if(!impl.back()){
+ return node_type_ptr_t(0);
+ }
+ else{
+ void_ptr &pool_first_ref = impl.end()[-2];
+ void_ptr &pool_last_ref = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+ node_type_ptr_t ret = holder.front();
+ holder.pop_front();
+ --this->internal_data.pool_size;
+ if(!internal_data.pool_size){
+ pool_first_ref = pool_last_ref = void_ptr(0);
+ }
+ else{
+ std::pair<void_ptr, void_ptr> data(holder.extract_data());
+ pool_first_ref = data.first;
+ pool_last_ref = data.second;
+ }
+ return ret;
+ }
+ }
+
+ void insert_iter_prolog(size_type n, difference_type d)
+ {
+ initialize_end_node(n);
+ const void* old_ptr = &impl[0];
+ //size_type old_capacity = capacity();
+ //size_type old_size = size();
+ impl.insert(impl.begin()+d, n, 0);
+ bool realloced = &impl[0] != old_ptr;
+ //Fix the pointers for the newly allocated buffer
+ if(realloced){
+ align_nodes(impl.begin(), impl.begin()+d);
+ }
+ }
+
+ template<typename InputIterator>
+ void assign_dispatch(InputIterator first, InputIterator last, boost::mpl::false_)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ iterator first1 = this->begin();
+ iterator last1 = this->end();
+ for ( ; first1 != last1 && first != last; ++first1, ++first)
+ *first1 = *first;
+ if (first == last){
+ this->erase(first1, last1);
+ }
+ else{
+ this->insert(last1, first, last);
+ }
+ }
+
+ template<typename Integer>
+ void assign_dispatch(Integer n, Integer t, boost::mpl::true_)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+ }
+
+ iterator priv_erase(const_iterator first, const_iterator last, allocator_v1)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
+ if(d1 != d2){
+ impl_iterator it1(impl.begin() + d1), it2(impl.begin() + d2);
+ for(impl_iterator it = it1; it != it2; ++it)
+ this->delete_node(*it);
+ impl_iterator e = impl.erase(it1, it2);
+ this->align_nodes(e, get_last_align());
+ }
+ return iterator(this->begin() + d1);
+ }
+
+ impl_iterator get_last_align()
+ {
+ return impl.end() - (ExtraPointers - 1);
+ }
+
+ const_impl_iterator get_last_align() const
+ {
+ return impl.cend() - (ExtraPointers - 1);
+ }
+
+ template<class AllocatorVersion>
+ iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
+ typename boost::container::containers_detail::enable_if_c
+ <boost::container::containers_detail::is_same<AllocatorVersion, allocator_v2>
+ ::value>::type * = 0)
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ return priv_erase(first, last, allocator_v1());
+ }
+
+ static node_type_ptr_t node_ptr_cast(const void_ptr &p)
+ {
+ using boost::get_pointer;
+ return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
+ {
+ using boost::get_pointer;
+ return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::get_pointer(p)));
+ }
+
+ static value_type& value(const void_ptr &p)
+ {
+ return node_ptr_cast(p)->value;
+ }
+
+ void initialize_end_node(size_type impl_capacity = 0)
+ {
+ if(impl.empty()){
+ impl.reserve(impl_capacity + ExtraPointers);
+ impl.resize (ExtraPointers, void_ptr(0));
+ impl[0] = &this->internal_data.end_node;
+ this->internal_data.end_node.up = &impl[0];
+ }
+ }
+
+ void readjust_end_node()
+ {
+ if(!this->impl.empty()){
+ void_ptr &end_node_ref = *(this->get_last_align()-1);
+ end_node_ref = this->get_end_node();
+ this->internal_data.end_node.up = &end_node_ref;
+ }
+ else{
+ this->internal_data.end_node.up = void_ptr(&this->internal_data.end_node.up);
+ }
+ }
+
+ node_type_ptr_t get_end_node() const
+ {
+ const node_type_base_t* cp = &this->internal_data.end_node;
+ node_type_base_t* p = const_cast<node_type_base_t*>(cp);
+ return node_ptr_cast(p);
+ }
+
+ template<class Iter>
+ void_ptr new_node(const void_ptr &up, Iter it)
+ {
+ node_type_ptr_t p = this->allocate_one();
+ try{
+ boost::container::construct_in_place(&*p, it);
+ p->set_pointer(up);
+ }
+ catch(...){
+ this->deallocate_one(p);
+ throw;
+ }
+ return p;
+ }
+
+ void delete_node(const void_ptr &p)
+ {
+ node_type_ptr_t n(node_ptr_cast(p));
+ n->~node_type_t();
+ this->put_in_pool(n);
+ }
+
+ static void align_nodes(impl_iterator first, impl_iterator last)
+ {
+ while(first!=last){
+ node_ptr_cast(*first)->up = void_ptr(&*first);
+ ++first;
+ }
+ }
+
+ void insert_not_iter(const_iterator position, size_type n, const T& t)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->insert_iter(position, cvalue_iterator(t, n), cvalue_iterator(), std::forward_iterator_tag());
+ }
+
+ template <class InputIterator>
+ void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::true_)
+ {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category category;
+ this->insert_iter(position, first, last, category());
+ }
+
+ template <class InputIterator>
+ void insert_iter(const_iterator position,InputIterator first,InputIterator last,std::input_iterator_tag)
+ {
+ for(; first!=last; ++first){
+ this->insert(position, *first);
+ }
+ }
+
+ template <class InputIterator>
+ iterator insert_iter(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
+ {
+ size_type n = (size_type)std::distance(first,last);
+ difference_type d = position-this->cbegin();
+ if(n){
+ this->insert_iter_prolog(n, d);
+ const impl_iterator it(impl.begin() + d);
+ this->insert_iter_fwd(it, first, last, n);
+ //Fix the pointers for the newly allocated buffer
+ this->align_nodes(it + n, get_last_align());
+ }
+ return this->begin() + d;
+ }
+
+ template <class FwdIterator>
+ void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v1)
+ {
+ size_type i=0;
+ try{
+ while(first!=last){
+ it[i] = this->new_node(void_ptr_ptr(&it[i]), first);
+ ++first;
+ ++i;
+ }
+ }
+ catch(...){
+ impl_iterator e = impl.erase(it + i, it + n);
+ this->align_nodes(e, get_last_align());
+ throw;
+ }
+ }
+
+ template <class FwdIterator>
+ void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
+ {
+ multiallocation_chain mem(get_al().allocate_individual(n));
+
+ size_type i = 0;
+ node_type_ptr_t p = 0;
+ try{
+ while(first != last){
+ p = mem.front();
+ mem.pop_front();
+ //This can throw
+ boost::container::construct_in_place(&*p, first);
+ p->set_pointer(void_ptr_ptr(&it[i]));
+ ++first;
+ it[i] = p;
+ ++i;
+ }
+ }
+ catch(...){
+ get_al().deallocate_one(p);
+ get_al().deallocate_many(boost::move(mem));
+ impl_iterator e = impl.erase(it+i, it+n);
+ this->align_nodes(e, get_last_align());
+ throw;
+ }
+ }
+
+ template <class FwdIterator>
+ void insert_iter_fwd(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n)
+ {
+ size_type i = 0;
+ node_type_ptr_t p = 0;
+ try{
+ while(first != last){
+ p = get_from_pool();
+ if(!p){
+ insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
+ break;
+ }
+ //This can throw
+ boost::container::construct_in_place(&*p, first);
+ p->set_pointer(void_ptr_ptr(&it[i]));
+ ++first;
+ it[i]=p;
+ ++i;
+ }
+ }
+ catch(...){
+ put_in_pool(p);
+ impl_iterator e = impl.erase(it+i, it+n);
+ this->align_nodes(e, get_last_align());
+ throw;
+ }
+ }
+
+ template <class InputIterator>
+ void insert_iter(const_iterator position, InputIterator first, InputIterator last, boost::mpl::false_)
+ {
+ this->insert_not_iter(position, first, last);
+ }
+
+ static void swap_impl(stable_vector& x,stable_vector& y)
+ {
+ using std::swap;
+ swap(x.get_al(),y.get_al());
+ swap(x.impl,y.impl);
+ swap(x.internal_data.pool_size, y.internal_data.pool_size);
+ x.readjust_end_node();
+ y.readjust_end_node();
+ }
+
+ #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+ bool invariant()const
+ {
+ if(impl.empty())
+ return !capacity() && !size();
+ if(get_end_node() != *(impl.end() - ExtraPointers)){
+ return false;
+ }
+ for(const_impl_iterator it = impl.begin(), it_end = get_last_align(); it != it_end; ++it){
+ if(const_void_ptr(node_ptr_cast(*it)->up) !=
+ const_void_ptr(const_void_ptr_ptr(&*it)))
+ return false;
+ }
+ size_type n = capacity()-size();
+ const void_ptr &pool_head = impl.back();
+ size_type num_pool = 0;
+ node_type_ptr_t p = node_ptr_cast(pool_head);
+ while(p){
+ ++num_pool;
+ p = node_ptr_cast(p->up);
+ }
+ return n >= num_pool;
+ }
+
+ class invariant_checker:private boost::noncopyable
+ {
+ const stable_vector* p;
+ public:
+ invariant_checker(const stable_vector& v):p(&v){}
+ ~invariant_checker(){BOOST_ASSERT(p->invariant());}
+ void touch(){}
+ };
+ #endif
+
+ struct ebo_holder
+ : node_allocator_type
+ {
+ ebo_holder(const allocator_type &a)
+ : node_allocator_type(a), pool_size(0), end_node()
+ {
+ this->set_end_pointer_to_default_constructed();
+ }
+
+ void set_end_pointer_to_default_constructed()
+ {
+ end_node.set_pointer(void_ptr(&end_node.up));
+ }
+
+ size_type pool_size;
+ node_type_base_t end_node;
+ } internal_data;
+
+ node_allocator_type &get_al() { return internal_data; }
+ const node_allocator_type &get_al() const { return internal_data; }
+
+ impl_type impl;
+ /// @endcond
+};
+
+template <typename T,typename A>
+bool operator==(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
+{
+ return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
+}
+
+template <typename T,typename A>
+bool operator< (const stable_vector<T,A>& x,const stable_vector<T,A>& y)
+{
+ return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+}
+
+template <typename T,typename A>
+bool operator!=(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
+{
+ return !(x==y);
+}
+
+template <typename T,typename A>
+bool operator> (const stable_vector<T,A>& x,const stable_vector<T,A>& y)
+{
+ return y<x;
+}
+
+template <typename T,typename A>
+bool operator>=(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
+{
+ return !(x<y);
+}
+
+template <typename T,typename A>
+bool operator<=(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
+{
+ return !(x>y);
+}
+
+// specialized algorithms:
+
+template <typename T, typename A>
+void swap(stable_vector<T,A>& x,stable_vector<T,A>& y)
+{
+ x.swap(y);
+}
+
+/// @cond
+
+#undef STABLE_VECTOR_CHECK_INVARIANT
+
+/// @endcond
+
+}}
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_STABLE_VECTOR_HPP
Added: branches/release/boost/container/string.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/string.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,2786 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1996,1997
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation. Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+
+#ifndef BOOST_CONTAINERS_STRING_HPP
+#define BOOST_CONTAINERS_STRING_HPP
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/algorithms.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/move/move.hpp>
+#include <boost/static_assert.hpp>
+
+#include <functional>
+#include <string>
+#include <stdexcept>
+#include <utility>
+#include <iterator>
+#include <memory>
+#include <algorithm>
+#include <iosfwd>
+#include <istream>
+#include <ostream>
+#include <ios>
+#include <locale>
+#include <cstddef>
+#include <climits>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/aligned_storage.hpp>
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+namespace containers_detail {
+// ------------------------------------------------------------
+// Class basic_string_base.
+
+// basic_string_base is a helper class that makes it it easier to write
+// an exception-safe version of basic_string. The constructor allocates,
+// but does not initialize, a block of memory. The destructor
+// deallocates, but does not destroy elements within, a block of
+// memory. The destructor assumes that the memory either is the internal buffer,
+// or else points to a block of memory that was allocated using _String_base's
+// allocator and whose size is this->m_storage.
+template <class A>
+class basic_string_base
+{
+ basic_string_base();
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base)
+
+ public:
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::value_type value_type;
+ typedef typename A::size_type size_type;
+
+ basic_string_base(const allocator_type& a)
+ : members_(a)
+ { init(); }
+
+ basic_string_base(const allocator_type& a, size_type n)
+ : members_(a)
+ {
+ this->init();
+ this->allocate_initial_block(n);
+ }
+
+ basic_string_base(BOOST_RV_REF(basic_string_base) b)
+ : members_(b.members_)
+ {
+ init();
+ this->swap(b);
+ }
+
+ ~basic_string_base()
+ {
+ this->deallocate_block();
+ if(!this->is_short()){
+ static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
+ }
+ }
+
+ private:
+
+ //This is the structure controlling a long string
+ struct long_t
+ {
+ size_type is_short : 1;
+ size_type length : (sizeof(size_type)*CHAR_BIT - 1);
+ size_type storage;
+ pointer start;
+
+ long_t()
+ {}
+
+ long_t(const long_t &other)
+ {
+ this->is_short = other.is_short;
+ length = other.length;
+ storage = other.storage;
+ start = other.start;
+ }
+
+ long_t &operator =(const long_t &other)
+ {
+ this->is_short = other.is_short;
+ length = other.length;
+ storage = other.storage;
+ start = other.start;
+ return *this;
+ }
+ };
+
+ //This type is the first part of the structure controlling a short string
+ //The "data" member stores
+ struct short_header
+ {
+ unsigned char is_short : 1;
+ unsigned char length : (CHAR_BIT - 1);
+ };
+
+ //This type has the same alignment and size as long_t but it's POD
+ //so, unlike long_t, it can be placed in a union
+
+ typedef typename boost::aligned_storage< sizeof(long_t),
+ containers_detail::alignment_of<long_t>::value>::type long_raw_t;
+
+ protected:
+ static const size_type MinInternalBufferChars = 8;
+ static const size_type AlignmentOfValueType =
+ alignment_of<value_type>::value;
+ static const size_type ShortDataOffset =
+ containers_detail::ct_rounded_size<sizeof(short_header), AlignmentOfValueType>::value;
+ static const size_type ZeroCostInternalBufferChars =
+ (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
+ static const size_type UnalignedFinalInternalBufferChars =
+ (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
+ ZeroCostInternalBufferChars : MinInternalBufferChars;
+
+ struct short_t
+ {
+ short_header h;
+ value_type data[UnalignedFinalInternalBufferChars];
+ };
+
+ union repr_t
+ {
+ long_raw_t r;
+ short_t s;
+
+ short_t &short_repr() const
+ { return *const_cast<short_t *>(&s); }
+
+ long_t &long_repr() const
+ { return *const_cast<long_t*>(reinterpret_cast<const long_t*>(&r)); }
+ };
+
+ struct members_holder
+ : public A
+ {
+ members_holder(const A &a)
+ : A(a)
+ {}
+
+ repr_t m_repr;
+ } members_;
+
+ const A &alloc() const
+ { return members_; }
+
+ A &alloc()
+ { return members_; }
+
+ static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
+
+ private:
+
+ static const size_type MinAllocation = InternalBufferChars*2;
+
+ protected:
+ bool is_short() const
+ { return static_cast<bool>(this->members_.m_repr.s.h.is_short != 0); }
+
+ void is_short(bool yes)
+ {
+ if(yes && !this->is_short()){
+ static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
+ }
+ else{
+ new(static_cast<void*>(&this->members_.m_repr.r))long_t();
+ }
+ this->members_.m_repr.s.h.is_short = yes;
+ }
+
+ private:
+ void init()
+ {
+ this->members_.m_repr.s.h.is_short = 1;
+ this->members_.m_repr.s.h.length = 0;
+ }
+
+ protected:
+
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::container::containers_detail::version<A>::value> alloc_version;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, pointer reuse = 0)
+ {
+ if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
+ reuse = pointer(0);
+ command &= ~(expand_fwd | expand_bwd);
+ }
+ return this->allocation_command
+ (command, limit_size, preferred_size, received_size, reuse, alloc_version());
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ const pointer &reuse,
+ allocator_v1)
+ {
+ (void)limit_size;
+ (void)reuse;
+ if(!(command & allocate_new))
+ return std::pair<pointer, bool>(pointer(0), false);
+ received_size = preferred_size;
+ return std::make_pair(this->alloc().allocate(received_size), false);
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ pointer reuse,
+ allocator_v2)
+ {
+ return this->alloc().allocation_command(command, limit_size, preferred_size,
+ received_size, reuse);
+ }
+
+ size_type next_capacity(size_type additional_objects) const
+ { return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects); }
+
+ void deallocate(pointer p, size_type n)
+ {
+ if (p && (n > InternalBufferChars))
+ this->alloc().deallocate(p, n);
+ }
+
+ void construct(pointer p, const value_type &value = value_type())
+ { new((void*)containers_detail::get_pointer(p)) value_type(value); }
+
+ void destroy(pointer p, size_type n)
+ {
+ for(; n--; ++p)
+ containers_detail::get_pointer(p)->~value_type();
+ }
+
+ void destroy(pointer p)
+ { containers_detail::get_pointer(p)->~value_type(); }
+
+ void allocate_initial_block(size_type n)
+ {
+ if (n <= this->max_size()) {
+ if(n > InternalBufferChars){
+ size_type new_cap = this->next_capacity(n);
+ pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
+ this->is_short(false);
+ this->priv_long_addr(p);
+ this->priv_size(0);
+ this->priv_storage(new_cap);
+ }
+ }
+ else
+ throw_length_error();
+ }
+
+ void deallocate_block()
+ { this->deallocate(this->priv_addr(), this->priv_storage()); }
+
+ size_type max_size() const
+ { return this->alloc().max_size() - 1; }
+
+ // Helper functions for exception handling.
+ void throw_length_error() const
+ { throw(std::length_error("basic_string")); }
+
+ void throw_out_of_range() const
+ { throw(std::out_of_range("basic_string")); }
+
+ protected:
+ size_type priv_capacity() const
+ { return this->priv_storage() - 1; }
+
+ pointer priv_short_addr() const
+ { return pointer(&this->members_.m_repr.short_repr().data[0]); }
+
+ pointer priv_long_addr() const
+ { return this->members_.m_repr.long_repr().start; }
+
+ pointer priv_addr() const
+ { return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start; }
+
+ void priv_long_addr(pointer addr)
+ { this->members_.m_repr.long_repr().start = addr; }
+
+ size_type priv_storage() const
+ { return this->is_short() ? priv_short_storage() : priv_long_storage(); }
+
+ size_type priv_short_storage() const
+ { return InternalBufferChars; }
+
+ size_type priv_long_storage() const
+ { return this->members_.m_repr.long_repr().storage; }
+
+ void priv_storage(size_type storage)
+ {
+ if(!this->is_short())
+ this->priv_long_storage(storage);
+ }
+
+ void priv_long_storage(size_type storage)
+ {
+ this->members_.m_repr.long_repr().storage = storage;
+ }
+
+ size_type priv_size() const
+ { return this->is_short() ? priv_short_size() : priv_long_size(); }
+
+ size_type priv_short_size() const
+ { return this->members_.m_repr.short_repr().h.length; }
+
+ size_type priv_long_size() const
+ { return this->members_.m_repr.long_repr().length; }
+
+ void priv_size(size_type sz)
+ {
+ if(this->is_short())
+ this->priv_short_size(sz);
+ else
+ this->priv_long_size(sz);
+ }
+
+ void priv_short_size(size_type sz)
+ {
+ this->members_.m_repr.s.h.length = (unsigned char)sz;
+ }
+
+ void priv_long_size(size_type sz)
+ {
+ this->members_.m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
+ }
+
+ void swap(basic_string_base& other)
+ {
+ if(this->is_short()){
+ if(other.is_short()){
+ std::swap(this->members_.m_repr, other.members_.m_repr);
+ }
+ else{
+ repr_t copied(this->members_.m_repr);
+ this->members_.m_repr.long_repr() = other.members_.m_repr.long_repr();
+ other.members_.m_repr = copied;
+ }
+ }
+ else{
+ if(other.is_short()){
+ repr_t copied(other.members_.m_repr);
+ other.members_.m_repr.long_repr() = this->members_.m_repr.long_repr();
+ this->members_.m_repr = copied;
+ }
+ else{
+ std::swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+ }
+ }
+
+ allocator_type & this_al = this->alloc(), &other_al = other.alloc();
+ if(this_al != other_al){
+ containers_detail::do_swap(this_al, other_al);
+ }
+ }
+};
+
+} //namespace containers_detail {
+
+/// @endcond
+
+//! The basic_string class represents a Sequence of characters. It contains all the
+//! usual operations of a Sequence, and, additionally, it contains standard string
+//! operations such as search and concatenation.
+//!
+//! The basic_string class is parameterized by character type, and by that type's
+//! Character Traits.
+//!
+//! This class has performance characteristics very much like vector<>, meaning,
+//! for example, that it does not perform reference-count or copy-on-write, and that
+//! concatenation of two strings is an O(N) operation.
+//!
+//! Some of basic_string's member functions use an unusual method of specifying positions
+//! and ranges. In addition to the conventional method using iterators, many of
+//! basic_string's member functions use a single value pos of type size_type to represent a
+//! position (in which case the position is begin() + pos, and many of basic_string's
+//! member functions use two values, pos and n, to represent a range. In that case pos is
+//! the beginning of the range and n is its size. That is, the range is
+//! [begin() + pos, begin() + pos + n).
+//!
+//! Note that the C++ standard does not specify the complexity of basic_string operations.
+//! In this implementation, basic_string has performance characteristics very similar to
+//! those of vector: access to a single character is O(1), while copy and concatenation
+//! are O(N).
+//!
+//! In this implementation, begin(),
+//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
+//! In this implementation, iterators are only invalidated by member functions that
+//! explicitly change the string's contents.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class CharT, class Traits = std::char_traits<CharT>, class A = std::allocator<CharT> >
+#else
+template <class CharT, class Traits, class A>
+#endif
+class basic_string
+ : private containers_detail::basic_string_base<A>
+{
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(basic_string)
+ typedef containers_detail::basic_string_base<A> base_t;
+ static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
+
+ protected:
+ // A helper class to use a char_traits as a function object.
+
+ template <class Tr>
+ struct Eq_traits
+ : public std::binary_function<typename Tr::char_type,
+ typename Tr::char_type,
+ bool>
+ {
+ bool operator()(const typename Tr::char_type& x,
+ const typename Tr::char_type& y) const
+ { return Tr::eq(x, y); }
+ };
+
+ template <class Tr>
+ struct Not_within_traits
+ : public std::unary_function<typename Tr::char_type, bool>
+ {
+ typedef const typename Tr::char_type* Pointer;
+ const Pointer m_first;
+ const Pointer m_last;
+
+ Not_within_traits(Pointer f, Pointer l)
+ : m_first(f), m_last(l) {}
+
+ bool operator()(const typename Tr::char_type& x) const
+ {
+ return std::find_if(m_first, m_last,
+ std::bind1st(Eq_traits<Tr>(), x)) == m_last;
+ }
+ };
+ /// @endcond
+
+ public:
+
+ //! The allocator type
+ typedef A allocator_type;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+ //! The type of object, CharT, stored in the string
+ typedef CharT value_type;
+ //! The second template parameter Traits
+ typedef Traits traits_type;
+ //! Pointer to CharT
+ typedef typename A::pointer pointer;
+ //! Const pointer to CharT
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to CharT
+ typedef typename A::reference reference;
+ //! Const reference to CharT
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! Iterator used to iterate through a string. It's a Random Access Iterator
+ typedef pointer iterator;
+ //! Const iterator used to iterate through a string. It's a Random Access Iterator
+ typedef const_pointer const_iterator;
+ //! Iterator used to iterate backwards through a string
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ //! Const iterator used to iterate backwards through a string
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ //! The largest possible value of type size_type. That is, size_type(-1).
+ static const size_type npos;
+
+ /// @cond
+ private:
+ typedef constant_iterator<CharT, difference_type> cvalue_iterator;
+ typedef typename base_t::allocator_v1 allocator_v1;
+ typedef typename base_t::allocator_v2 allocator_v2;
+ typedef typename base_t::alloc_version alloc_version;
+ /// @endcond
+
+ public: // Constructor, destructor, assignment.
+ /// @cond
+ struct reserve_t {};
+
+ basic_string(reserve_t, size_type n,
+ const allocator_type& a = allocator_type())
+ : base_t(a, n + 1)
+ { this->priv_terminate_string(); }
+
+ /// @endcond
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ explicit basic_string(const allocator_type& a = allocator_type())
+ : base_t(a, InternalBufferChars)
+ { this->priv_terminate_string(); }
+
+ //! <b>Effects</b>: Copy constructs a basic_string.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
+ basic_string(const basic_string& s)
+ : base_t(s.alloc())
+ { this->priv_range_initialize(s.begin(), s.end()); }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ basic_string(BOOST_RV_REF(basic_string) s)
+ : base_t(boost::move((base_t&)s))
+ {}
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by a specific number of characters of the s string.
+ basic_string(const basic_string& s, size_type pos, size_type n = npos,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ {
+ if (pos > s.size())
+ this->throw_out_of_range();
+ else
+ this->priv_range_initialize
+ (s.begin() + pos, s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
+ }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by a specific number of characters of the s c-string.
+ basic_string(const CharT* s, size_type n,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->priv_range_initialize(s, s + n); }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by the null-terminated s c-string.
+ basic_string(const CharT* s,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->priv_range_initialize(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and is initialized by n copies of c.
+ basic_string(size_type n, CharT c,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ {
+ this->priv_range_initialize(cvalue_iterator(c, n),
+ cvalue_iterator());
+ }
+
+ //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
+ //! and a range of iterators.
+ template <class InputIterator>
+ basic_string(InputIterator f, InputIterator l,
+ const allocator_type& a = allocator_type())
+ : base_t(a)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIterator, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_initialize_dispatch(f, l, Result());
+ }
+
+ //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ ~basic_string()
+ {}
+
+ //! <b>Effects</b>: Copy constructs a string.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) s)
+ {
+ if (&s != this)
+ this->assign(s.begin(), s.end());
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ basic_string& operator=(BOOST_RV_REF(basic_string) ms)
+ {
+ basic_string &s = ms;
+ if (&s != this){
+ this->swap(s);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assignment from a null-terminated c-string.
+ basic_string& operator=(const CharT* s)
+ { return this->assign(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Assignment from character.
+ basic_string& operator=(CharT c)
+ { return this->assign(static_cast<size_type>(1), c); }
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return this->priv_addr(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return this->priv_addr(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return this->priv_addr(); }
+
+
+ //! <b>Effects</b>: Returns an iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return this->priv_addr() + this->priv_size(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->priv_addr() + this->priv_size(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return this->priv_addr() + this->priv_size(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->priv_addr() + this->priv_size()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin() const
+ { return this->crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->priv_addr() + this->priv_size()); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(this->priv_addr()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->priv_addr()); }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return this->alloc(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->priv_size(); }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type length() const
+ { return this->size(); }
+
+ //! <b>Effects</b>: Returns the largest possible size of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return base_t::max_size(); }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n, CharT c)
+ {
+ if (n <= size())
+ this->erase(this->begin() + n, this->end());
+ else
+ this->append(n - this->size(), c);
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n)
+ { resize(n, this->priv_null()); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws
+ void reserve(size_type res_arg)
+ {
+ if (res_arg > this->max_size())
+ this->throw_length_error();
+
+ if (this->capacity() < res_arg){
+ size_type n = containers_detail::max_value(res_arg, this->size()) + 1;
+ size_type new_cap = this->next_capacity(n);
+ pointer new_start = this->allocation_command
+ (allocate_new, n, new_cap, new_cap).first;
+ size_type new_length = 0;
+
+ new_length += priv_uninitialized_copy
+ (this->priv_addr(), this->priv_addr() + this->priv_size(), new_start);
+ this->priv_construct_null(new_start + new_length);
+ this->deallocate_block();
+ this->is_short(false);
+ this->priv_long_addr(new_start);
+ this->priv_size(new_length);
+ this->priv_storage(new_cap);
+ }
+ }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return this->priv_capacity(); }
+
+ //! <b>Effects</b>: Erases all the elements of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the vector.
+ void clear()
+ {
+ if (!empty()) {
+ Traits::assign(*this->priv_addr(), this->priv_null());
+ this->priv_size(0);
+ }
+ }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the string is unchanged
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ {
+ //Check if shrinking is possible
+ if(this->priv_storage() > InternalBufferChars){
+ //Check if we should pass from dynamically allocated buffer
+ //to the internal storage
+ if(this->priv_size() < (InternalBufferChars)){
+ //Dynamically allocated buffer attributes
+ pointer long_addr = this->priv_long_addr();
+ size_type long_storage = this->priv_long_storage();
+ size_type long_size = this->priv_long_size();
+ //Shrink from allocated buffer to the internal one, including trailing null
+ Traits::copy( containers_detail::get_pointer(this->priv_short_addr())
+ , containers_detail::get_pointer(long_addr)
+ , long_size+1);
+ this->is_short(true);
+ this->alloc().deallocate(long_addr, long_storage);
+ }
+ else{
+ //Shrinking in dynamic buffer
+ this->priv_shrink_to_fit_dynamic_buffer(alloc_version());
+ }
+ }
+ }
+
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->priv_size(); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n)
+ { return *(this->priv_addr() + n); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n) const
+ { return *(this->priv_addr() + n); }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n) {
+ if (n >= size())
+ this->throw_out_of_range();
+ return *(this->priv_addr() + n);
+ }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n) const {
+ if (n >= size())
+ this->throw_out_of_range();
+ return *(this->priv_addr() + n);
+ }
+
+ //! <b>Effects</b>: Calls append(str.data, str.size()).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& operator+=(const basic_string& s)
+ { return this->append(s); }
+
+ //! <b>Effects</b>: Calls append(s).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& operator+=(const CharT* s)
+ { return this->append(s); }
+
+ //! <b>Effects</b>: Calls append(1, c).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& operator+=(CharT c)
+ { this->push_back(c); return *this; }
+
+ //! <b>Effects</b>: Calls append(str.data(), str.size()).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& append(const basic_string& s)
+ { return this->append(s.begin(), s.end()); }
+
+ //! <b>Requires</b>: pos <= str.size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to append
+ //! as the smaller of n and str.size() - pos and calls append(str.data() + pos, rlen).
+ //!
+ //! <b>Throws</b>: If memory allocation throws and out_of_range if pos > str.size()
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& append(const basic_string& s, size_type pos, size_type n)
+ {
+ if (pos > s.size())
+ this->throw_out_of_range();
+ return this->append(s.begin() + pos,
+ s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
+ }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Effects</b>: The function replaces the string controlled by *this with
+ //! a string of length size() + n whose irst size() elements are a copy of the
+ //! original string controlled by *this and whose remaining
+ //! elements are a copy of the initial n elements of s.
+ //!
+ //! <b>Throws</b>: If memory allocation throws length_error if size() + n > max_size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& append(const CharT* s, size_type n)
+ { return this->append(s, s + n); }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Effects</b>: Calls append(s, traits::length(s)).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& append(const CharT* s)
+ { return this->append(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Equivalent to append(basic_string(n, c)).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& append(size_type n, CharT c)
+ { return this->append(cvalue_iterator(c, n), cvalue_iterator()); }
+
+ //! <b>Requires</b>: [first,last) is a valid range.
+ //!
+ //! <b>Effects</b>: Equivalent to append(basic_string(first, last)).
+ //!
+ //! <b>Returns</b>: *this
+ template <class InputIter>
+ basic_string& append(InputIter first, InputIter last)
+ { this->insert(this->end(), first, last); return *this; }
+
+ //! <b>Effects</b>: Equivalent to append(static_cast<size_type>(1), c).
+ void push_back(CharT c)
+ {
+ if (this->priv_size() < this->capacity()){
+ this->priv_construct_null(this->priv_addr() + (this->priv_size() + 1));
+ Traits::assign(this->priv_addr()[this->priv_size()], c);
+ this->priv_size(this->priv_size()+1);
+ }
+ else{
+ //No enough memory, insert a new object at the end
+ this->append((size_type)1, c);
+ }
+ }
+
+ //! <b>Effects</b>: Equivalent to assign(str, 0, npos).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& assign(const basic_string& s)
+ { return this->operator=(s); }
+
+ //! <b>Effects</b>: The function replaces the string controlled by *this
+ //! with a string of length str.size() whose elements are a copy of the string
+ //! controlled by str. Leaves str in a valid but unspecified state.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& assign(BOOST_RV_REF(basic_string) ms)
+ { return this->swap(ms), *this; }
+
+ //! <b>Requires</b>: pos <= str.size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to assign as
+ //! the smaller of n and str.size() - pos and calls assign(str.data() + pos rlen).
+ //!
+ //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > str.size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& assign(const basic_string& s,
+ size_type pos, size_type n) {
+ if (pos > s.size())
+ this->throw_out_of_range();
+ return this->assign(s.begin() + pos,
+ s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
+ }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Effects</b>: Replaces the string controlled by *this with a string of
+ //! length n whose elements are a copy of those pointed to by s.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or length_error if n > max_size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& assign(const CharT* s, size_type n)
+ { return this->assign(s, s + n); }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Effects</b>: Calls assign(s, traits::length(s)).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& assign(const CharT* s)
+ { return this->assign(s, s + Traits::length(s)); }
+
+ //! <b>Effects</b>: Equivalent to assign(basic_string(n, c)).
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& assign(size_type n, CharT c)
+ { return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
+ //!
+ //! <b>Returns</b>: *this
+ template <class InputIter>
+ basic_string& assign(InputIter first, InputIter last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIter, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ return this->priv_assign_dispatch(first, last, Result());
+ }
+
+ //! <b>Requires</b>: pos <= size().
+ //!
+ //! <b>Effects</b>: Calls insert(pos, str.data(), str.size()).
+ //!
+ //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& insert(size_type pos, const basic_string& s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ if (this->size() > this->max_size() - s.size())
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, s.begin(), s.end());
+ return *this;
+ }
+
+ //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to insert as
+ //! the smaller of n and str.size() - pos2 and calls insert(pos1, str.data() + pos2, rlen).
+ //!
+ //! <b>Throws</b>: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& insert(size_type pos1, const basic_string& s,
+ size_type pos2, size_type n)
+ {
+ if (pos1 > this->size() || pos2 > s.size())
+ this->throw_out_of_range();
+ size_type len = containers_detail::min_value(n, s.size() - pos2);
+ if (this->size() > this->max_size() - len)
+ this->throw_length_error();
+ const CharT *beg_ptr = containers_detail::get_pointer(s.begin()) + pos2;
+ const CharT *end_ptr = beg_ptr + len;
+ this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
+ return *this;
+ }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT and pos <= size().
+ //!
+ //! <b>Effects</b>: Replaces the string controlled by *this with a string of length size() + n
+ //! whose first pos elements are a copy of the initial elements of the original string
+ //! controlled by *this and whose next n elements are a copy of the elements in s and whose
+ //! remaining elements are a copy of the remaining elements of the original string controlled by *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size() or
+ //! length_error if size() + n > max_size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& insert(size_type pos, const CharT* s, size_type n)
+ {
+ if (pos > this->size())
+ this->throw_out_of_range();
+ if (this->size() > this->max_size() - n)
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, s, s + n);
+ return *this;
+ }
+
+ //! <b>Requires</b>: pos <= size() and s points to an array of at least traits::length(s) + 1 elements of CharT
+ //!
+ //! <b>Effects</b>: Calls insert(pos, s, traits::length(s)).
+ //!
+ //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size()
+ //! length_error if size() > max_size() - Traits::length(s)
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& insert(size_type pos, const CharT* s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ size_type len = Traits::length(s);
+ if (this->size() > this->max_size() - len)
+ this->throw_length_error();
+ this->insert(this->priv_addr() + pos, s, s + len);
+ return *this;
+ }
+
+ //! <b>Effects</b>: Equivalent to insert(pos, basic_string(n, c)).
+ //!
+ //! <b>Throws</b>: If memory allocation throws, out_of_range if pos > size()
+ //! length_error if size() > max_size() - n
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& insert(size_type pos, size_type n, CharT c)
+ {
+ if (pos > this->size())
+ this->throw_out_of_range();
+ if (this->size() > this->max_size() - n)
+ this->throw_length_error();
+ this->insert(const_iterator(this->priv_addr() + pos), n, c);
+ return *this;
+ }
+
+ //! <b>Requires</b>: p is a valid iterator on *this.
+ //!
+ //! <b>Effects</b>: inserts a copy of c before the character referred to by p.
+ //!
+ //! <b>Returns</b>: An iterator which refers to the copy of the inserted character.
+ iterator insert(const_iterator p, CharT c)
+ {
+ size_type new_offset = p - this->priv_addr() + 1;
+ this->insert(p, cvalue_iterator(c, 1), cvalue_iterator());
+ return this->priv_addr() + new_offset;
+ }
+
+
+ //! <b>Requires</b>: p is a valid iterator on *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
+ //!
+ //! <b>Returns</b>: An iterator which refers to the copy of the first
+ //! inserted character, or p if n == 0.
+ void insert(const_iterator p, size_type n, CharT c)
+ {
+ this->insert(p, cvalue_iterator(c, n), cvalue_iterator());
+ }
+
+ //! <b>Requires</b>: p is a valid iterator on *this. [first,last) is a valid range.
+ //!
+ //! <b>Effects</b>: Equivalent to insert(p - begin(), basic_string(first, last)).
+ //!
+ //! <b>Returns</b>: An iterator which refers to the copy of the first
+ //! inserted character, or p if first == last.
+ template <class InputIter>
+ void insert(const_iterator p, InputIter first, InputIter last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIter, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(p, first, last, Result());
+ }
+
+ //! <b>Requires</b>: pos <= size()
+ //!
+ //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
+ //! The function then replaces the string controlled by *this with a string of length size() - xlen
+ //! whose first pos elements are a copy of the initial elements of the original string controlled by *this,
+ //! and whose remaining elements are a copy of the elements of the original string controlled by *this
+ //! beginning at position pos + xlen.
+ //!
+ //! <b>Throws</b>: out_of_range if pos > size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& erase(size_type pos = 0, size_type n = npos)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ erase(this->priv_addr() + pos, this->priv_addr() + pos + containers_detail::min_value(n, size() - pos));
+ return *this;
+ }
+
+ //! <b>Effects</b>: Removes the character referred to by p.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
+ //! erased. If no such element exists, end() is returned.
+ iterator erase(const_iterator p)
+ {
+ // The move includes the terminating null.
+ CharT *ptr = const_cast<CharT*>(containers_detail::get_pointer(p));
+ Traits::move(ptr,
+ containers_detail::get_pointer(p + 1),
+ this->priv_size() - (p - this->priv_addr()));
+ this->priv_size(this->priv_size()-1);
+ return iterator(ptr);
+ }
+
+ //! <b>Requires</b>: first and last are valid iterators on *this, defining a range [first,last).
+ //!
+ //! <b>Effects</b>: Removes the characters in the range [first,last).
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
+ //! the other elements being erased. If no such element exists, end() is returned.
+ iterator erase(const_iterator first, const_iterator last)
+ {
+ CharT * f = const_cast<CharT*>(containers_detail::get_pointer(first));
+ if (first != last) { // The move includes the terminating null.
+ size_type num_erased = last - first;
+ Traits::move(f,
+ containers_detail::get_pointer(last),
+ (this->priv_size() + 1)-(last - this->priv_addr()));
+ size_type new_length = this->priv_size() - num_erased;
+ this->priv_size(new_length);
+ }
+ return iterator(f);
+ }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Effects</b>: Equivalent to erase(size() - 1, 1).
+ void pop_back()
+ {
+ Traits::assign(this->priv_addr()[this->priv_size()-1], this->priv_null());
+ this->priv_size(this->priv_size()-1);;
+ }
+
+ //! <b>Requires</b>: pos1 <= size().
+ //!
+ //! <b>Effects</b>: Calls replace(pos1, n1, str.data(), str.size()).
+ //!
+ //! <b>Throws</b>: if memory allocation throws or out_of_range if pos1 > size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(size_type pos1, size_type n1, const basic_string& str)
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos1);
+ if (this->size() - len >= this->max_size() - str.size())
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
+ str.begin(), str.end());
+ }
+
+ //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size().
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to be
+ //! inserted as the smaller of n2 and str.size() - pos2 and calls
+ //! replace(pos1, n1, str.data() + pos2, rlen).
+ //!
+ //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or pos2 > str.size().
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(size_type pos1, size_type n1,
+ const basic_string& str, size_type pos2, size_type n2)
+ {
+ if (pos1 > size() || pos2 > str.size())
+ this->throw_out_of_range();
+ const size_type len1 = containers_detail::min_value(n1, size() - pos1);
+ const size_type len2 = containers_detail::min_value(n2, str.size() - pos2);
+ if (this->size() - len1 >= this->max_size() - len2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len1,
+ str.priv_addr() + pos2, str.priv_addr() + pos2 + len2);
+ }
+
+ //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+ //!
+ //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the
+ //! smaller of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error.
+ //! Otherwise, the function replaces the string controlled by *this with a string of
+ //! length size() - xlen + n2 whose first pos1 elements are a copy of the initial elements
+ //! of the original string controlled by *this, whose next n2 elements are a copy of the
+ //! initial n2 elements of s, and whose remaining elements are a copy of the elements of
+ //! the original string controlled by *this beginning at position pos + xlen.
+ //!
+ //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+ //! if the length of the resulting string would exceed max_size()
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(size_type pos1, size_type n1,
+ const CharT* s, size_type n2)
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos1);
+ if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
+ s, s + n2);
+ }
+
+ //! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+ //!
+ //! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller
+ //! of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error. Otherwise,
+ //! the function replaces the string controlled by *this with a string of length size() - xlen + n2
+ //! whose first pos1 elements are a copy of the initial elements of the original string controlled
+ //! by *this, whose next n2 elements are a copy of the initial n2 elements of s, and whose
+ //! remaining elements are a copy of the elements of the original string controlled by *this
+ //! beginning at position pos + xlen.
+ //!
+ //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+ //! if the length of the resulting string would exceed max_size()
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(size_type pos, size_type n1, const CharT* s)
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos);
+ const size_type n2 = Traits::length(s);
+ if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
+ s, s + Traits::length(s));
+ }
+
+ //! <b>Requires</b>: pos1 <= size().
+ //!
+ //! <b>Effects</b>: Equivalent to replace(pos1, n1, basic_string(n2, c)).
+ //!
+ //! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
+ //! if the length of the resulting string would exceed max_size()
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(size_type pos1, size_type n1, size_type n2, CharT c)
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n1, size() - pos1);
+ if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+ this->throw_length_error();
+ return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len, n2, c);
+ }
+
+ //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
+ //!
+ //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, str).
+ //!
+ //! <b>Throws</b>: if memory allocation throws
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str)
+ { return this->replace(i1, i2, str.begin(), str.end()); }
+
+ //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and
+ //! s points to an array of at least n elements
+ //!
+ //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, s, n).
+ //!
+ //! <b>Throws</b>: if memory allocation throws
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n)
+ { return this->replace(i1, i2, s, s + n); }
+
+ //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and s points to an
+ //! array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, s, traits::length(s)).
+ //!
+ //! <b>Throws</b>: if memory allocation throws
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s)
+ { return this->replace(i1, i2, s, s + Traits::length(s)); }
+
+ //! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges.
+ //!
+ //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, basic_string(n, c)).
+ //!
+ //! <b>Throws</b>: if memory allocation throws
+ //!
+ //! <b>Returns</b>: *this
+ basic_string& replace(const_iterator i1, const_iterator i2, size_type n, CharT c)
+ {
+ const size_type len = static_cast<size_type>(i2 - i1);
+ if (len >= n) {
+ Traits::assign(const_cast<CharT*>(containers_detail::get_pointer(i1)), n, c);
+ erase(i1 + n, i2);
+ }
+ else {
+ Traits::assign(const_cast<CharT*>(containers_detail::get_pointer(i1)), len, c);
+ insert(i2, n - len, c);
+ }
+ return *this;
+ }
+
+ //! <b>Requires</b>: [begin(),i1), [i1,i2) and [j1,j2) are valid ranges.
+ //!
+ //! <b>Effects</b>: Calls replace(i1 - begin(), i2 - i1, basic_string(j1, j2)).
+ //!
+ //! <b>Throws</b>: if memory allocation throws
+ //!
+ //! <b>Returns</b>: *this
+ template <class InputIter>
+ basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InputIter, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ return this->priv_replace_dispatch(i1, i2, j1, j2, Result());
+ }
+
+ //! <b>Requires</b>: pos <= size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to copy as the
+ //! smaller of n and size() - pos. s shall designate an array of at least rlen elements.
+ //! The function then replaces the string designated by s with a string of length rlen
+ //! whose elements are a copy of the string controlled by *this beginning at position pos.
+ //! The function does not append a null object to the string designated by s.
+ //!
+ //! <b>Throws</b>: if memory allocation throws, out_of_range if pos > size().
+ //!
+ //! <b>Returns</b>: rlen
+ size_type copy(CharT* s, size_type n, size_type pos = 0) const
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ const size_type len = containers_detail::min_value(n, size() - pos);
+ Traits::copy(s, containers_detail::get_pointer(this->priv_addr() + pos), len);
+ return len;
+ }
+
+ //! <b>Effects</b>: *this contains the same sequence of characters that was in s,
+ //! s contains the same sequence of characters that was in *this.
+ //!
+ //! <b>Throws</b>: Nothing
+ void swap(basic_string& x)
+ { base_t::swap(x); }
+
+ //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
+ //!
+ //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+ //!
+ //! <b>Complexity</b>: constant time.
+ const CharT* c_str() const
+ { return containers_detail::get_pointer(this->priv_addr()); }
+
+ //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
+ //!
+ //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+ //!
+ //! <b>Complexity</b>: constant time.
+ const CharT* data() const
+ { return containers_detail::get_pointer(this->priv_addr()); }
+
+ //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
+ //! of the following conditions obtain: 19 pos <= xpos and xpos + str.size() <= size();
+ //! 2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+ size_type find(const basic_string& s, size_type pos = 0) const
+ { return find(s.c_str(), pos, s.size()); }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(s,n),pos).
+ size_type find(const CharT* s, size_type pos, size_type n) const
+ {
+ if (pos + n > size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const const_iterator result =
+ std::search(containers_detail::get_pointer(this->priv_addr() + pos),
+ containers_detail::get_pointer(finish),
+ s, s + n, Eq_traits<Traits>());
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find(basic_string(s), pos).
+ size_type find(const CharT* s, size_type pos = 0) const
+ { return find(s, pos, Traits::length(s)); }
+
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos).
+ size_type find(CharT c, size_type pos = 0) const
+ {
+ if (pos >= size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const const_iterator result =
+ std::find_if(this->priv_addr() + pos, finish,
+ std::bind2nd(Eq_traits<Traits>(), c));
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Determines the highest position xpos, if possible, such
+ //! that both of the following conditions obtain:
+ //! a) xpos <= pos and xpos + str.size() <= size();
+ //! b) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+ size_type rfind(const basic_string& str, size_type pos = npos) const
+ { return rfind(str.c_str(), pos, str.size()); }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: rfind(basic_string(s, n), pos).
+ size_type rfind(const CharT* s, size_type pos, size_type n) const
+ {
+ const size_type len = size();
+
+ if (n > len)
+ return npos;
+ else if (n == 0)
+ return containers_detail::min_value(len, pos);
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - n, pos) + n;
+ const const_iterator result = find_end(begin(), last,
+ s, s + n,
+ Eq_traits<Traits>());
+ return result != last ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: pos <= size() and s points to an array of at least
+ //! traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: rfind(basic_string(s), pos).
+ size_type rfind(const CharT* s, size_type pos = npos) const
+ { return rfind(s, pos, Traits::length(s)); }
+
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: rfind(basic_string<CharT,traits,Allocator>(1,c),pos).
+ size_type rfind(CharT c, size_type pos = npos) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
+ const_reverse_iterator rresult =
+ std::find_if(const_reverse_iterator(last), rend(),
+ std::bind2nd(Eq_traits<Traits>(), c));
+ return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
+ //! following conditions obtain: a) pos <= xpos and xpos < size();
+ //! b) traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+ size_type find_first_of(const basic_string& s, size_type pos = 0) const
+ { return find_first_of(s.c_str(), pos, s.size()); }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_first_of(basic_string(s, n), pos).
+ size_type find_first_of(const CharT* s, size_type pos, size_type n) const
+ {
+ if (pos >= size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const_iterator result = std::find_first_of(this->priv_addr() + pos, finish,
+ s, s + n,
+ Eq_traits<Traits>());
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_first_of(basic_string(s), pos).
+ size_type find_first_of(const CharT* s, size_type pos = 0) const
+ { return find_first_of(s, pos, Traits::length(s)); }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_first_of(basic_string<CharT,traits,Allocator>(1,c), pos).
+ size_type find_first_of(CharT c, size_type pos = 0) const
+ { return find(c, pos); }
+
+ //! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
+ //! the following conditions obtain: a) xpos <= pos and xpos < size(); b)
+ //! traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+ size_type find_last_of(const basic_string& str, size_type pos = npos) const
+ { return find_last_of(str.c_str(), pos, str.size()); }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_last_of(basic_string(s, n), pos).
+ size_type find_last_of(const CharT* s, size_type pos, size_type n) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = this->priv_addr() + containers_detail::min_value(len - 1, pos) + 1;
+ const const_reverse_iterator rresult =
+ std::find_first_of(const_reverse_iterator(last), rend(),
+ s, s + n,
+ Eq_traits<Traits>());
+ return rresult != rend() ? (rresult.base() - 1) - this->priv_addr() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_last_of(basic_string<CharT,traits,Allocator>(1,c),pos).
+ size_type find_last_of(const CharT* s, size_type pos = npos) const
+ { return find_last_of(s, pos, Traits::length(s)); }
+
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_last_of(basic_string(s), pos).
+ size_type find_last_of(CharT c, size_type pos = npos) const
+ { return rfind(c, pos); }
+
+ //! <b>Effects</b>: Determines the lowest position xpos, if possible, such that
+ //! both of the following conditions obtain:
+ //! a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), str.at(I)) for no
+ //! element I of the string controlled by str.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+ size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
+ { return find_first_not_of(str.c_str(), pos, str.size()); }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_first_not_of(basic_string(s, n), pos).
+ size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const
+ {
+ if (pos > size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const_iterator result = std::find_if(this->priv_addr() + pos, finish,
+ Not_within_traits<Traits>(s, s + n));
+ return result != finish ? result - this->priv_addr() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_first_not_of(basic_string(s), pos).
+ size_type find_first_not_of(const CharT* s, size_type pos = 0) const
+ { return find_first_not_of(s, pos, Traits::length(s)); }
+
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_first_not_of(basic_string(1, c), pos).
+ size_type find_first_not_of(CharT c, size_type pos = 0) const
+ {
+ if (pos > size())
+ return npos;
+ else {
+ pointer finish = this->priv_addr() + this->priv_size();
+ const_iterator result
+ = std::find_if(this->priv_addr() + pos, finish,
+ std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
+ return result != finish ? result - begin() : npos;
+ }
+ }
+
+ //! <b>Effects</b>: Determines the highest position xpos, if possible, such that
+ //! both of the following conditions obtain: a) xpos <= pos and xpos < size();
+ //! b) traits::eq(at(xpos), str.at(I)) for no element I of the string controlled by str.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+ size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
+ { return find_last_not_of(str.c_str(), pos, str.size()); }
+
+ //! <b>Requires</b>: s points to an array of at least n elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_last_not_of(basic_string(s, n), pos).
+ size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
+ const const_reverse_iterator rresult =
+ std::find_if(const_reverse_iterator(last), rend(),
+ Not_within_traits<Traits>(s, s + n));
+ return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_last_not_of(basic_string(s), pos).
+ size_type find_last_not_of(const CharT* s, size_type pos = npos) const
+ { return find_last_not_of(s, pos, Traits::length(s)); }
+
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: find_last_not_of(basic_string(1, c), pos).
+ size_type find_last_not_of(CharT c, size_type pos = npos) const
+ {
+ const size_type len = size();
+
+ if (len < 1)
+ return npos;
+ else {
+ const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
+ const_reverse_iterator rresult =
+ std::find_if(const_reverse_iterator(last), rend(),
+ std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
+ return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+ }
+ }
+
+ //! <b>Requires</b>: Requires: pos <= size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+ //! the smaller of n and size() - pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or out_of_range if pos > size().
+ //!
+ //! <b>Returns</b>: basic_string<CharT,traits,Allocator>(data()+pos,rlen).
+ basic_string substr(size_type pos = 0, size_type n = npos) const
+ {
+ if (pos > size())
+ this->throw_out_of_range();
+ return basic_string(this->priv_addr() + pos,
+ this->priv_addr() + pos + containers_detail::min_value(n, size() - pos), this->alloc());
+ }
+
+ //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+ //! the smaller of size() and str.size(). The function then compares the two strings by
+ //! calling traits::compare(data(), str.data(), rlen).
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: The nonzero result if the result of the comparison is nonzero.
+ //! Otherwise, returns a value < 0 if size() < str.size(), a 0 value if size() == str.size(),
+ //! and value > 0 if size() > str.size()
+ int compare(const basic_string& str) const
+ { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), str.priv_addr(), str.priv_addr() + str.priv_size()); }
+
+ //! <b>Requires</b>: pos1 <= size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+ //! the smaller of
+ //!
+ //! <b>Throws</b>: out_of_range if pos1 > size()
+ //!
+ //! <b>Returns</b>:basic_string(*this,pos1,n1).compare(str).
+ int compare(size_type pos1, size_type n1, const basic_string& str) const
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ return s_compare(this->priv_addr() + pos1,
+ this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
+ str.priv_addr(), str.priv_addr() + str.priv_size());
+ }
+
+ //! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
+ //!
+ //! <b>Effects</b>: Determines the effective length rlen of the string to copy as
+ //! the smaller of
+ //!
+ //! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size()
+ //!
+ //! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
+ int compare(size_type pos1, size_type n1,
+ const basic_string& str, size_type pos2, size_type n2) const {
+ if (pos1 > size() || pos2 > str.size())
+ this->throw_out_of_range();
+ return s_compare(this->priv_addr() + pos1,
+ this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
+ str.priv_addr() + pos2,
+ str.priv_addr() + pos2 + containers_detail::min_value(n2, size() - pos2));
+ }
+
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Returns</b>: compare(basic_string(s)).
+ int compare(const CharT* s) const
+ { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s, s + Traits::length(s)); }
+
+
+ //! <b>Requires</b>: pos1 > size() and s points to an array of at least n2 elements of CharT.
+ //!
+ //! <b>Throws</b>: out_of_range if pos1 > size()
+ //!
+ //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+ int compare(size_type pos1, size_type n1,
+ const CharT* s, size_type n2 = npos) const
+ {
+ if (pos1 > size())
+ this->throw_out_of_range();
+ return s_compare(this->priv_addr() + pos1,
+ this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
+ s, s + n2);
+ }
+
+ //! <b>Requires</b>: pos1 > size() and s points to an array of at least traits::length(s) + 1 elements of CharT.
+ //!
+ //! <b>Throws</b>: out_of_range if pos1 > size()
+ //!
+ //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+ int compare(size_type pos1, size_type n1, const CharT* s) const
+ { return this->compare(pos1, n1, s, Traits::length(s)); }
+
+ /// @cond
+ private:
+ static int s_compare(const_pointer f1, const_pointer l1,
+ const_pointer f2, const_pointer l2)
+ {
+ const difference_type n1 = l1 - f1;
+ const difference_type n2 = l2 - f2;
+ const int cmp = Traits::compare(containers_detail::get_pointer(f1),
+ containers_detail::get_pointer(f2),
+ containers_detail::min_value(n1, n2));
+ return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
+ }
+
+ void priv_shrink_to_fit_dynamic_buffer(allocator_v1)
+ {
+ //Allocate a new buffer.
+ size_type real_cap = 0;
+ pointer long_addr = this->priv_long_addr();
+ size_type long_size = this->priv_long_size();
+ size_type long_storage = this->priv_long_storage();
+ //We can make this nothrow as chars are always NoThrowCopyables
+ try{
+ std::pair<pointer, bool> ret = this->allocation_command
+ (allocate_new, long_size+1, long_size+1, real_cap, long_addr);
+ //Copy and update
+ Traits::copy( containers_detail::get_pointer(ret.first)
+ , containers_detail::get_pointer(this->priv_long_addr())
+ , long_size+1);
+ this->priv_long_addr(ret.first);
+ this->priv_storage(real_cap);
+ //And release old buffer
+ this->alloc().deallocate(long_addr, long_storage);
+ }
+ catch(...){
+ return;
+ }
+ }
+
+ void priv_shrink_to_fit_dynamic_buffer(allocator_v2)
+ {
+ size_type received_size;
+ if(this->alloc().allocation_command
+ ( shrink_in_place | nothrow_allocation
+ , this->priv_long_storage(), this->priv_long_size()+1
+ , received_size, this->priv_long_addr()).first){
+ this->priv_storage(received_size);
+ }
+ }
+
+ void priv_construct_null(pointer p)
+ { this->construct(p, 0); }
+
+ static CharT priv_null()
+ { return (CharT) 0; }
+
+ // Helper functions used by constructors. It is a severe error for
+ // any of them to be called anywhere except from within constructors.
+ void priv_terminate_string()
+ { this->priv_construct_null(this->priv_addr() + this->priv_size()); }
+
+ template <class InputIter>
+ void priv_range_initialize(InputIter f, InputIter l,
+ std::input_iterator_tag)
+ {
+ this->allocate_initial_block(InternalBufferChars);
+ this->priv_construct_null(this->priv_addr() + this->priv_size());
+ this->append(f, l);
+ }
+
+ template <class ForwardIter>
+ void priv_range_initialize(ForwardIter f, ForwardIter l,
+ std::forward_iterator_tag)
+ {
+ difference_type n = std::distance(f, l);
+ this->allocate_initial_block(containers_detail::max_value<difference_type>(n+1, InternalBufferChars));
+ priv_uninitialized_copy(f, l, this->priv_addr());
+ this->priv_size(n);
+ this->priv_terminate_string();
+ }
+
+ template <class InputIter>
+ void priv_range_initialize(InputIter f, InputIter l)
+ {
+ typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ this->priv_range_initialize(f, l, Category());
+ }
+
+ template <class Integer>
+ void priv_initialize_dispatch(Integer n, Integer x, containers_detail::true_)
+ {
+ this->allocate_initial_block(containers_detail::max_value<difference_type>(n+1, InternalBufferChars));
+ priv_uninitialized_fill_n(this->priv_addr(), n, x);
+ this->priv_size(n);
+ this->priv_terminate_string();
+ }
+
+ template <class InputIter>
+ void priv_initialize_dispatch(InputIter f, InputIter l, containers_detail::false_)
+ { this->priv_range_initialize(f, l); }
+
+ template<class FwdIt, class Count> inline
+ void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
+ {
+ //Save initial position
+ FwdIt init = first;
+
+ BOOST_TRY{
+ //Construct objects
+ for (; count--; ++first){
+ this->construct(first, val);
+ }
+ }
+ BOOST_CATCH(...){
+ //Call destructors
+ for (; init != first; ++init){
+ this->destroy(init);
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
+
+ template<class InpIt, class FwdIt> inline
+ size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
+ {
+ //Save initial destination position
+ FwdIt dest_init = dest;
+ size_type constructed = 0;
+
+ BOOST_TRY{
+ //Try to build objects
+ for (; first != last; ++dest, ++first, ++constructed){
+ this->construct(dest, *first);
+ }
+ }
+ BOOST_CATCH(...){
+ //Call destructors
+ for (; constructed--; ++dest_init){
+ this->destroy(dest_init);
+ }
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ return (constructed);
+ }
+
+ template <class Integer>
+ basic_string& priv_assign_dispatch(Integer n, Integer x, containers_detail::true_)
+ { return this->assign((size_type) n, (CharT) x); }
+
+ template <class InputIter>
+ basic_string& priv_assign_dispatch(InputIter f, InputIter l,
+ containers_detail::false_)
+ {
+ size_type cur = 0;
+ CharT *ptr = containers_detail::get_pointer(this->priv_addr());
+ while (f != l && cur != this->priv_size()) {
+ Traits::assign(*ptr, *f);
+ ++f;
+ ++cur;
+ ++ptr;
+ }
+ if (f == l)
+ this->erase(this->priv_addr() + cur, this->priv_addr() + this->priv_size());
+ else
+ this->append(f, l);
+ return *this;
+ }
+
+ template <class InputIter>
+ void priv_insert(const_iterator p, InputIter first, InputIter last, std::input_iterator_tag)
+ {
+ for ( ; first != last; ++first, ++p) {
+ p = this->insert(p, *first);
+ }
+ }
+
+ template <class ForwardIter>
+ void priv_insert(const_iterator position, ForwardIter first,
+ ForwardIter last, std::forward_iterator_tag)
+ {
+ if (first != last) {
+ size_type n = std::distance(first, last);
+ size_type remaining = this->capacity() - this->priv_size();
+ const size_type old_size = this->size();
+ pointer old_start = this->priv_addr();
+ bool enough_capacity = false;
+ std::pair<pointer, bool> allocation_ret;
+ size_type new_cap = 0;
+
+ //Check if we have enough capacity
+ if (remaining >= n){
+ enough_capacity = true;
+ }
+ else {
+ //Otherwise expand current buffer or allocate new storage
+ new_cap = this->next_capacity(n);
+ allocation_ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
+ new_cap, new_cap, old_start);
+
+ //Check forward expansion
+ if(old_start == allocation_ret.first){
+ enough_capacity = true;
+ this->priv_storage(new_cap);
+ }
+ }
+
+ //Reuse same buffer
+ if(enough_capacity){
+ const size_type elems_after =
+ this->priv_size() - (position - this->priv_addr());
+ size_type old_length = this->priv_size();
+ if (elems_after >= n) {
+ pointer pointer_past_last = this->priv_addr() + this->priv_size() + 1;
+ priv_uninitialized_copy(this->priv_addr() + (this->priv_size() - n + 1),
+ pointer_past_last, pointer_past_last);
+
+ this->priv_size(this->priv_size()+n);
+ Traits::move(const_cast<CharT*>(containers_detail::get_pointer(position + n)),
+ containers_detail::get_pointer(position),
+ (elems_after - n) + 1);
+ this->priv_copy(first, last, const_cast<CharT*>(containers_detail::get_pointer(position)));
+ }
+ else {
+ ForwardIter mid = first;
+ std::advance(mid, elems_after + 1);
+
+ priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1);
+ this->priv_size(this->priv_size() + (n - elems_after));
+ priv_uninitialized_copy
+ (position, const_iterator(this->priv_addr() + old_length + 1),
+ this->priv_addr() + this->priv_size());
+ this->priv_size(this->priv_size() + elems_after);
+ this->priv_copy(first, mid, const_cast<CharT*>(containers_detail::get_pointer(position)));
+ }
+ }
+ else{
+ pointer new_start = allocation_ret.first;
+ if(!allocation_ret.second){
+ //Copy data to new buffer
+ size_type new_length = 0;
+ //This can't throw, since characters are POD
+ new_length += priv_uninitialized_copy
+ (const_iterator(this->priv_addr()), position, new_start);
+ new_length += priv_uninitialized_copy
+ (first, last, new_start + new_length);
+ new_length += priv_uninitialized_copy
+ (position, const_iterator(this->priv_addr() + this->priv_size()),
+ new_start + new_length);
+ this->priv_construct_null(new_start + new_length);
+
+ this->deallocate_block();
+ this->is_short(false);
+ this->priv_long_addr(new_start);
+ this->priv_long_size(new_length);
+ this->priv_long_storage(new_cap);
+ }
+ else{
+ //value_type is POD, so backwards expansion is much easier
+ //than with vector<T>
+ value_type *oldbuf = containers_detail::get_pointer(old_start);
+ value_type *newbuf = containers_detail::get_pointer(new_start);
+ const value_type *pos = containers_detail::get_pointer(position);
+ size_type before = pos - oldbuf;
+
+ //First move old data
+ Traits::move(newbuf, oldbuf, before);
+ Traits::move(newbuf + before + n, pos, old_size - before);
+ //Now initialize the new data
+ priv_uninitialized_copy(first, last, new_start + before);
+ this->priv_construct_null(new_start + (old_size + n));
+ this->is_short(false);
+ this->priv_long_addr(new_start);
+ this->priv_long_size(old_size + n);
+ this->priv_long_storage(new_cap);
+ }
+ }
+ }
+ }
+
+ template <class Integer>
+ void priv_insert_dispatch(const_iterator p, Integer n, Integer x,
+ containers_detail::true_)
+ { insert(p, (size_type) n, (CharT) x); }
+
+ template <class InputIter>
+ void priv_insert_dispatch(const_iterator p, InputIter first, InputIter last,
+ containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ priv_insert(p, first, last, Category());
+ }
+
+ template <class InputIterator, class OutIterator>
+ void priv_copy(InputIterator first, InputIterator last, OutIterator result)
+ {
+ for ( ; first != last; ++first, ++result)
+ Traits::assign(*result, *first);
+ }
+
+ void priv_copy(const CharT* first, const CharT* last, CharT* result)
+ { Traits::copy(result, first, last - first); }
+
+ template <class Integer>
+ basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+ Integer n, Integer x,
+ containers_detail::true_)
+ { return this->replace(first, last, (size_type) n, (CharT) x); }
+
+ template <class InputIter>
+ basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+ InputIter f, InputIter l,
+ containers_detail::false_)
+ {
+ typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ return this->priv_replace(first, last, f, l, Category());
+ }
+
+
+ template <class InputIter>
+ basic_string& priv_replace(const_iterator first, const_iterator last,
+ InputIter f, InputIter l, std::input_iterator_tag)
+ {
+ for ( ; first != last && f != l; ++first, ++f)
+ Traits::assign(*first, *f);
+
+ if (f == l)
+ this->erase(first, last);
+ else
+ this->insert(last, f, l);
+ return *this;
+ }
+
+ template <class ForwardIter>
+ basic_string& priv_replace(const_iterator first, const_iterator last,
+ ForwardIter f, ForwardIter l,
+ std::forward_iterator_tag)
+ {
+ difference_type n = std::distance(f, l);
+ const difference_type len = last - first;
+ if (len >= n) {
+ this->priv_copy(f, l, const_cast<CharT*>(containers_detail::get_pointer(first)));
+ this->erase(first + n, last);
+ }
+ else {
+ ForwardIter m = f;
+ std::advance(m, len);
+ this->priv_copy(f, m, const_cast<CharT*>(containers_detail::get_pointer(first)));
+ this->insert(last, m, l);
+ }
+ return *this;
+ }
+ /// @endcond
+};
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+ <char
+ ,std::char_traits<char>
+ ,std::allocator<char> >
+string;
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+ <wchar_t
+ ,std::char_traits<wchar_t>
+ ,std::allocator<wchar_t> >
+wstring;
+
+/// @cond
+
+template <class CharT, class Traits, class A>
+const typename basic_string<CharT,Traits,A>::size_type
+basic_string<CharT,Traits,A>::npos
+ = (typename basic_string<CharT,Traits,A>::size_type) -1;
+
+/// @endcond
+
+// ------------------------------------------------------------
+// Non-member functions.
+
+// Operator+
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ str_t result(reserve, x.size() + y.size(), x.alloc());
+ result.append(x);
+ result.append(y);
+ return result;
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+ operator+(
+ BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+ , const basic_string<CharT,Traits,A>& y)
+{
+ mx += y;
+ return boost::move(mx);
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+ operator+(const basic_string<CharT,Traits,A>& x,
+ BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+ typedef typename basic_string<CharT,Traits,A>::size_type size_type;
+ return my.replace(size_type(0), size_type(0), x);
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const CharT* s, const basic_string<CharT,Traits,A>& y)
+{
+ typedef basic_string<CharT, Traits, A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ const typename str_t::size_type n = Traits::length(s);
+ str_t result(reserve, n + y.size());
+ result.append(s, s + n);
+ result.append(y);
+ return result;
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(const CharT* s,
+ BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+ typedef typename basic_string<CharT,Traits,A>::size_type size_type;
+ return boost::move(my.get().replace(size_type(0), size_type(0), s));
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(CharT c, const basic_string<CharT,Traits,A>& y)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ str_t result(reserve, 1 + y.size());
+ result.push_back(c);
+ result.append(y);
+ return result;
+}
+
+template <class CharT, class Traits, class A> inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(CharT c,
+ BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+ typedef typename basic_string<CharT,Traits,A>::size_type size_type;
+ return my.replace(size_type(0), size_type(0), &c, &c + 1);
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ const typename str_t::size_type n = Traits::length(s);
+ str_t result(reserve, x.size() + n, x.alloc());
+ result.append(x);
+ result.append(s, s + n);
+ return result;
+}
+
+template <class CharT, class Traits, class A>
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+ , const CharT* s)
+{
+ mx += s;
+ return boost::move(mx);
+}
+
+template <class CharT, class Traits, class A>
+inline basic_string<CharT,Traits,A>
+operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
+{
+ typedef basic_string<CharT,Traits,A> str_t;
+ typedef typename str_t::reserve_t reserve_t;
+ reserve_t reserve;
+ str_t result(reserve, x.size() + 1, x.alloc());
+ result.append(x);
+ result.push_back(c);
+ return result;
+}
+
+template <class CharT, class Traits, class A>
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+( BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+ , const CharT c)
+{
+ mx += c;
+ return boost::move(mx);
+}
+
+// Operator== and operator!=
+
+template <class CharT, class Traits, class A>
+inline bool
+operator==(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+{
+ return x.size() == y.size() &&
+ Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator==(const CharT* s, const basic_string<CharT,Traits,A>& y)
+{
+ typename basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
+ return n == y.size() && Traits::compare(s, y.data(), n) == 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator==(const basic_string<CharT,Traits,A>& x, const CharT* s)
+{
+ typename basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
+ return x.size() == n && Traits::compare(x.data(), s, n) == 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator!=(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+ { return !(x == y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator!=(const CharT* s, const basic_string<CharT,Traits,A>& y)
+ { return !(s == y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator!=(const basic_string<CharT,Traits,A>& x, const CharT* s)
+ { return !(x == s); }
+
+
+// Operator< (and also >, <=, and >=).
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<(const basic_string<CharT,Traits,A>& x, const basic_string<CharT,Traits,A>& y)
+{
+ return x.compare(y) < 0;
+// return basic_string<CharT,Traits,A>
+// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<(const CharT* s, const basic_string<CharT,Traits,A>& y)
+{
+ return y.compare(s) > 0;
+// basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
+// return basic_string<CharT,Traits,A>
+// ::s_compare(s, s + n, y.begin(), y.end()) < 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<(const basic_string<CharT,Traits,A>& x,
+ const CharT* s)
+{
+ return x.compare(s) < 0;
+// basic_string<CharT,Traits,A>::size_type n = Traits::length(s);
+// return basic_string<CharT,Traits,A>
+// ::s_compare(x.begin(), x.end(), s, s + n) < 0;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y) {
+ return y < x;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>(const CharT* s, const basic_string<CharT,Traits,A>& y) {
+ return y < s;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>(const basic_string<CharT,Traits,A>& x, const CharT* s)
+{
+ return s < x;
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<=(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+{
+ return !(y < x);
+}
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<=(const CharT* s, const basic_string<CharT,Traits,A>& y)
+ { return !(y < s); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator<=(const basic_string<CharT,Traits,A>& x, const CharT* s)
+ { return !(s < x); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>=(const basic_string<CharT,Traits,A>& x,
+ const basic_string<CharT,Traits,A>& y)
+ { return !(x < y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>=(const CharT* s, const basic_string<CharT,Traits,A>& y)
+ { return !(s < y); }
+
+template <class CharT, class Traits, class A>
+inline bool
+operator>=(const basic_string<CharT,Traits,A>& x, const CharT* s)
+ { return !(x < s); }
+
+// Swap.
+template <class CharT, class Traits, class A>
+inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>& y)
+{ x.swap(y); }
+
+/// @cond
+// I/O.
+namespace containers_detail {
+
+template <class CharT, class Traits>
+inline bool
+string_fill(std::basic_ostream<CharT, Traits>& os,
+ std::basic_streambuf<CharT, Traits>* buf,
+ std::size_t n)
+{
+ CharT f = os.fill();
+ std::size_t i;
+ bool ok = true;
+
+ for (i = 0; i < n; i++)
+ ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
+ return ok;
+}
+
+} //namespace containers_detail {
+/// @endcond
+
+template <class CharT, class Traits, class A>
+std::basic_ostream<CharT, Traits>&
+operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,A>& s)
+{
+ typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
+ bool ok = false;
+
+ if (sentry) {
+ ok = true;
+ typename basic_string<CharT,Traits,A>::size_type n = s.size();
+ typename basic_string<CharT,Traits,A>::size_type pad_len = 0;
+ const bool left = (os.flags() & std::ios::left) != 0;
+ const std::size_t w = os.width(0);
+ std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
+
+ if (w != 0 && n < w)
+ pad_len = w - n;
+
+ if (!left)
+ ok = containers_detail::string_fill(os, buf, pad_len);
+
+ ok = ok &&
+ buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
+
+ if (left)
+ ok = ok && containers_detail::string_fill(os, buf, pad_len);
+ }
+
+ if (!ok)
+ os.setstate(std::ios_base::failbit);
+
+ return os;
+}
+
+
+template <class CharT, class Traits, class A>
+std::basic_istream<CharT, Traits>&
+operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s)
+{
+ typename std::basic_istream<CharT, Traits>::sentry sentry(is);
+
+ if (sentry) {
+ std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+ const std::ctype<CharT>& ctype = std::use_facet<std::ctype<CharT> >(is.getloc());
+
+ s.clear();
+ std::size_t n = is.width(0);
+ if (n == 0)
+ n = static_cast<std::size_t>(-1);
+ else
+ s.reserve(n);
+
+ while (n-- > 0) {
+ typename Traits::int_type c1 = buf->sbumpc();
+
+ if (Traits::eq_int_type(c1, Traits::eof())) {
+ is.setstate(std::ios_base::eofbit);
+ break;
+ }
+ else {
+ CharT c = Traits::to_char_type(c1);
+
+ if (ctype.is(std::ctype<CharT>::space, c)) {
+ if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof()))
+ is.setstate(std::ios_base::failbit);
+ break;
+ }
+ else
+ s.push_back(c);
+ }
+ }
+
+ // If we have read no characters, then set failbit.
+ if (s.size() == 0)
+ is.setstate(std::ios_base::failbit);
+ }
+ else
+ is.setstate(std::ios_base::failbit);
+
+ return is;
+}
+
+template <class CharT, class Traits, class A>
+std::basic_istream<CharT, Traits>&
+getline(std::istream& is, basic_string<CharT,Traits,A>& s,CharT delim)
+{
+ typename basic_string<CharT,Traits,A>::size_type nread = 0;
+ typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
+ if (sentry) {
+ std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
+ s.clear();
+
+ while (nread < s.max_size()) {
+ int c1 = buf->sbumpc();
+ if (Traits::eq_int_type(c1, Traits::eof())) {
+ is.setstate(std::ios_base::eofbit);
+ break;
+ }
+ else {
+ ++nread;
+ CharT c = Traits::to_char_type(c1);
+ if (!Traits::eq(c, delim))
+ s.push_back(c);
+ else
+ break; // Character is extracted but not appended.
+ }
+ }
+ }
+ if (nread == 0 || nread >= s.max_size())
+ is.setstate(std::ios_base::failbit);
+
+ return is;
+}
+
+template <class CharT, class Traits, class A>
+inline std::basic_istream<CharT, Traits>&
+getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s)
+{
+ return getline(is, s, '\n');
+}
+
+template <class Ch, class A>
+inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v)
+{
+ return hash_range(v.begin(), v.end());
+}
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class C, class T, class A>
+struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+*/
+}
+
+/// @endcond
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINERS_STRING_HPP
Added: branches/release/boost/container/vector.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/container/vector.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -0,0 +1,2002 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_VECTOR_HPP
+#define BOOST_CONTAINERS_CONTAINERS_VECTOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/container_fwd.hpp>
+
+#include <cstddef>
+#include <memory>
+#include <algorithm>
+#include <stdexcept>
+#include <iterator>
+#include <utility>
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/move/move_helpers.hpp>
+#include <boost/container/detail/version_type.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/algorithms.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/container_fwd.hpp>
+#include <boost/move/move.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/advanced_insert_int.hpp>
+
+namespace boost {
+namespace container {
+
+/// @cond
+
+namespace containers_detail {
+
+//! Const vector_iterator used to iterate through a vector.
+template <class Pointer>
+class vector_const_iterator
+ : public std::iterator<std::random_access_iterator_tag
+ ,const typename std::iterator_traits<Pointer>::value_type
+ ,typename std::iterator_traits<Pointer>::difference_type
+ ,typename boost::pointer_to_other
+ <Pointer
+ ,const typename std::iterator_traits<Pointer>::value_type
+ >::type
+ ,const typename std::iterator_traits<Pointer>::value_type &>
+{
+ public:
+ typedef typename std::iterator_traits<Pointer>::value_type value_type;
+ typedef typename std::iterator_traits<Pointer>::difference_type difference_type;
+ typedef typename boost::pointer_to_other<Pointer, value_type>::type pointer;
+ typedef const value_type& reference;
+
+ /// @cond
+ protected:
+ Pointer m_ptr;
+
+ public:
+ Pointer get_ptr() const { return m_ptr; }
+ explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){}
+ /// @endcond
+
+ public:
+
+ //Constructors
+ vector_const_iterator() : m_ptr(0){}
+
+ //Pointer like operators
+ reference operator*() const
+ { return *m_ptr; }
+
+ const value_type * operator->() const
+ { return containers_detail::get_pointer(m_ptr); }
+
+ reference operator[](difference_type off) const
+ { return m_ptr[off]; }
+
+ //Increment / Decrement
+ vector_const_iterator& operator++()
+ { ++m_ptr; return *this; }
+
+ vector_const_iterator operator++(int)
+ { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); }
+
+ vector_const_iterator& operator--()
+ { --m_ptr; return *this; }
+
+ vector_const_iterator operator--(int)
+ { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); }
+
+ //Arithmetic
+ vector_const_iterator& operator+=(difference_type off)
+ { m_ptr += off; return *this; }
+
+ vector_const_iterator operator+(difference_type off) const
+ { return vector_const_iterator(m_ptr+off); }
+
+ friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right)
+ { return vector_const_iterator(off + right.m_ptr); }
+
+ vector_const_iterator& operator-=(difference_type off)
+ { m_ptr -= off; return *this; }
+
+ vector_const_iterator operator-(difference_type off) const
+ { return vector_const_iterator(m_ptr-off); }
+
+ difference_type operator-(const vector_const_iterator& right) const
+ { return m_ptr - right.m_ptr; }
+
+ //Comparison operators
+ bool operator== (const vector_const_iterator& r) const
+ { return m_ptr == r.m_ptr; }
+
+ bool operator!= (const vector_const_iterator& r) const
+ { return m_ptr != r.m_ptr; }
+
+ bool operator< (const vector_const_iterator& r) const
+ { return m_ptr < r.m_ptr; }
+
+ bool operator<= (const vector_const_iterator& r) const
+ { return m_ptr <= r.m_ptr; }
+
+ bool operator> (const vector_const_iterator& r) const
+ { return m_ptr > r.m_ptr; }
+
+ bool operator>= (const vector_const_iterator& r) const
+ { return m_ptr >= r.m_ptr; }
+};
+
+//! Iterator used to iterate through a vector
+template <class Pointer>
+class vector_iterator
+ : public vector_const_iterator<Pointer>
+{
+ public:
+ explicit vector_iterator(Pointer ptr)
+ : vector_const_iterator<Pointer>(ptr)
+ {}
+
+ public:
+ typedef typename std::iterator_traits<Pointer>::value_type value_type;
+ typedef typename vector_const_iterator<Pointer>::difference_type difference_type;
+ typedef Pointer pointer;
+ typedef value_type& reference;
+
+ //Constructors
+ vector_iterator()
+ {}
+
+ //Pointer like operators
+ reference operator*() const
+ { return *this->m_ptr; }
+
+ value_type* operator->() const
+ { return containers_detail::get_pointer(this->m_ptr); }
+
+ reference operator[](difference_type off) const
+ { return this->m_ptr[off]; }
+
+ //Increment / Decrement
+ vector_iterator& operator++()
+ { ++this->m_ptr; return *this; }
+
+ vector_iterator operator++(int)
+ { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); }
+
+ vector_iterator& operator--()
+ { --this->m_ptr; return *this; }
+
+ vector_iterator operator--(int)
+ { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); }
+
+ // Arithmetic
+ vector_iterator& operator+=(difference_type off)
+ { this->m_ptr += off; return *this; }
+
+ vector_iterator operator+(difference_type off) const
+ { return vector_iterator(this->m_ptr+off); }
+
+ friend vector_iterator operator+(difference_type off, const vector_iterator& right)
+ { return vector_iterator(off + right.m_ptr); }
+
+ vector_iterator& operator-=(difference_type off)
+ { this->m_ptr -= off; return *this; }
+
+ vector_iterator operator-(difference_type off) const
+ { return vector_iterator(this->m_ptr-off); }
+
+ difference_type operator-(const vector_const_iterator<Pointer>& right) const
+ { return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; }
+};
+
+template <class T, class A>
+struct vector_value_traits
+{
+ typedef T value_type;
+ typedef A allocator_type;
+ static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr_after_move = trivial_dctr;
+ //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_copy = has_trivial_copy<value_type>::value;
+ static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
+ static const bool trivial_assign = has_trivial_assign<value_type>::value;
+ static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
+
+ //This is the anti-exception array destructor
+ //to deallocate values already constructed
+ typedef typename containers_detail::if_c
+ <trivial_dctr
+ ,containers_detail::null_scoped_destructor_n<allocator_type>
+ ,containers_detail::scoped_destructor_n<allocator_type>
+ >::type OldArrayDestructor;
+ //This is the anti-exception array destructor
+ //to destroy objects created with copy construction
+ typedef typename containers_detail::if_c
+ <nothrow_copy
+ ,containers_detail::null_scoped_destructor_n<allocator_type>
+ ,containers_detail::scoped_destructor_n<allocator_type>
+ >::type ArrayDestructor;
+ //This is the anti-exception array deallocator
+ typedef typename containers_detail::if_c
+ <nothrow_copy
+ ,containers_detail::null_scoped_array_deallocator<allocator_type>
+ ,containers_detail::scoped_array_deallocator<allocator_type>
+ >::type ArrayDeallocator;
+};
+
+//!This struct deallocates and allocated memory
+template <class A>
+struct vector_alloc_holder
+{
+ typedef typename A::pointer pointer;
+ typedef typename A::size_type size_type;
+ typedef typename A::value_type value_type;
+ typedef vector_value_traits<value_type, A> value_traits;
+
+ //Constructor, does not throw
+ vector_alloc_holder(const A &a)
+ : members_(a)
+ {}
+
+ //Destructor
+ ~vector_alloc_holder()
+ {
+ this->prot_destroy_all();
+ this->prot_deallocate();
+ }
+
+ typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef containers_detail::integral_constant<unsigned,
+ boost::container::containers_detail::version<A>::value> alloc_version;
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0)
+ {
+ return allocation_command(command, limit_size, preferred_size,
+ received_size, reuse, alloc_version());
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ const pointer &reuse,
+ allocator_v1)
+ {
+ (void)limit_size;
+ (void)reuse;
+ if(!(command & allocate_new))
+ return std::pair<pointer, bool>(pointer(0), false);
+ received_size = preferred_size;
+ return std::make_pair(this->alloc().allocate(received_size), false);
+ }
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size,
+ const pointer &reuse,
+ allocator_v2)
+ {
+ return this->alloc().allocation_command
+ (command, limit_size, preferred_size, received_size, reuse);
+ }
+
+ size_type next_capacity(size_type additional_objects) const
+ { return get_next_capacity(this->alloc().max_size(), this->members_.m_capacity, additional_objects); }
+
+ struct members_holder
+ : public A
+ {
+ private:
+ members_holder(const members_holder&);
+
+ public:
+ members_holder(const A &alloc)
+ : A(alloc), m_start(0), m_size(0), m_capacity(0)
+ {}
+
+ pointer m_start;
+ size_type m_size;
+ size_type m_capacity;
+ } members_;
+
+ A &alloc()
+ { return members_; }
+
+ const A &alloc() const
+ { return members_; }
+
+ protected:
+ void prot_deallocate()
+ {
+ if(!this->members_.m_capacity) return;
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ this->members_.m_start = 0;
+ this->members_.m_size = 0;
+ this->members_.m_capacity = 0;
+ }
+
+ void destroy(value_type* p)
+ {
+ if(!value_traits::trivial_dctr)
+ containers_detail::get_pointer(p)->~value_type();
+ }
+
+ void destroy_n(value_type* p, size_type n)
+ {
+ if(!value_traits::trivial_dctr)
+ for(; n--; ++p) p->~value_type();
+ }
+
+ void prot_destroy_all()
+ {
+ this->destroy_n(containers_detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->members_.m_size = 0;
+ }
+};
+
+} //namespace containers_detail {
+/// @endcond
+
+//! \class vector
+//! A vector is a sequence that supports random access to elements, constant
+//! time insertion and removal of elements at the end, and linear time insertion
+//! and removal of elements at the beginning or in the middle. The number of
+//! elements in a vector may vary dynamically; memory management is automatic.
+//! boost::container::vector is similar to std::vector but it's compatible
+//! with shared memory and memory mapped files.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template <class T, class A = std::allocator<T> >
+#else
+template <class T, class A>
+#endif
+class vector : private containers_detail::vector_alloc_holder<A>
+{
+ /// @cond
+ typedef vector<T, A> self_t;
+ typedef containers_detail::vector_alloc_holder<A> base_t;
+ /// @endcond
+ public:
+ //! The type of object, T, stored in the vector
+ typedef T value_type;
+ //! Pointer to T
+ typedef typename A::pointer pointer;
+ //! Const pointer to T
+ typedef typename A::const_pointer const_pointer;
+ //! Reference to T
+ typedef typename A::reference reference;
+ //! Const reference to T
+ typedef typename A::const_reference const_reference;
+ //! An unsigned integral type
+ typedef typename A::size_type size_type;
+ //! A signed integral type
+ typedef typename A::difference_type difference_type;
+ //! The allocator type
+ typedef A allocator_type;
+ //! The random access iterator
+ typedef containers_detail::vector_iterator<pointer> iterator;
+ //! The random access const_iterator
+ typedef containers_detail::vector_const_iterator<pointer> const_iterator;
+
+ //! Iterator used to iterate backwards through a vector.
+ typedef std::reverse_iterator<iterator>
+ reverse_iterator;
+ //! Const iterator used to iterate backwards through a vector.
+ typedef std::reverse_iterator<const_iterator>
+ const_reverse_iterator;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+
+ /// @cond
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(vector)
+ typedef containers_detail::advanced_insert_aux_int<T, T*> advanced_insert_aux_int_t;
+ typedef containers_detail::vector_value_traits<value_type, A> value_traits;
+
+ typedef typename base_t::allocator_v1 allocator_v1;
+ typedef typename base_t::allocator_v2 allocator_v2;
+ typedef typename base_t::alloc_version alloc_version;
+
+ typedef constant_iterator<T, difference_type> cvalue_iterator;
+ typedef repeat_iterator<T, difference_type> repeat_it;
+ typedef boost::move_iterator<repeat_it> repeat_move_it;
+ /// @endcond
+
+ public:
+
+ //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ explicit vector(const A& a = A())
+ : base_t(a)
+ {}
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts n default contructed values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit vector(size_type n)
+ : base_t(allocator_type())
+ {
+ //Allocate
+ size_type real_cap;
+ std::pair<pointer, bool> ret =
+ this->allocation_command(allocate_new, n, n, real_cap, this->members_.m_start);
+ T *new_mem = containers_detail::get_pointer(ret.first);
+ //Anti-exception rollback
+ typename value_traits::ArrayDeallocator scoped_alloc(new_mem, this->alloc(), real_cap);
+ //Default constructor
+ containers_detail::default_construct_aux_proxy<T, T*, size_type> proxy(n);
+ proxy.uninitialized_copy_all_to(new_mem);
+ //All ok, commit
+ this->members_.m_start = ret.first;
+ this->members_.m_size = n;
+ this->members_.m_capacity = real_cap;
+ scoped_alloc.release();
+ }
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ vector(size_type n, const T& value, const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->insert(this->cend(), n, value); }
+
+ //! <b>Effects</b>: Copy constructs a vector.
+ //!
+ //! <b>Postcondition</b>: x == *this.
+ //!
+ //! <b>Complexity</b>: Linear to the elements x contains.
+ vector(const vector<T, A>& x)
+ : base_t(static_cast<const base_t&>(x).alloc())
+ { *this = x; }
+
+ //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ vector(BOOST_RV_REF(vector) mx)
+ : base_t(static_cast<base_t&>(mx).alloc())
+ { this->swap(mx); }
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the vector.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InIt>
+ vector(InIt first, InIt last, const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->assign(first, last); }
+
+ //! <b>Effects</b>: Destroys the vector. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~vector()
+ {} //vector_alloc_holder clears the data
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator begin()
+ { return iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator begin() const
+ { return const_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns an iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator end()
+ { return iterator(this->members_.m_start + this->members_.m_size); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator end() const
+ { return this->cend(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rbegin()
+ { return reverse_iterator(this->end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rbegin()const
+ { return this->crbegin(); }
+
+ //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reverse_iterator rend()
+ { return reverse_iterator(this->begin()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->members_.m_start + this->members_.m_size); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin()const
+ { return const_reverse_iterator(this->end());}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->begin()); }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return *this->members_.m_start; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return *this->members_.m_start; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back()
+ { return this->members_.m_start[this->members_.m_size - 1]; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back() const
+ { return this->members_.m_start[this->members_.m_size - 1]; }
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ pointer data()
+ { return this->members_.m_start; }
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_pointer data() const
+ { return this->members_.m_start; }
+
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type size() const
+ { return this->members_.m_size; }
+
+ //! <b>Effects</b>: Returns the largest possible size of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type max_size() const
+ { return this->alloc().max_size(); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
+ { return this->members_.m_capacity; }
+
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return !this->members_.m_size; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n)
+ { return this->members_.m_start[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n) const
+ { return this->members_.m_start[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n)
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
+
+ //! <b>Requires</b>: size() < n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n) const
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return this->alloc(); }
+
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->alloc(); }
+
+ stored_allocator_type &get_stored_allocator()
+ { return this->alloc(); }
+
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //!
+ //! <b>Throws</b>: If memory allocation allocation throws or T's copy/move constructor throws.
+ void reserve(size_type new_cap)
+ {
+ if (this->capacity() < new_cap){
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ bool same_buffer_start;
+ size_type real_cap = 0;
+ std::pair<pointer, bool> ret =
+ this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ new_cap, new_cap, real_cap, this->members_.m_start);
+
+ //Check for forward expansion
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->members_.m_capacity = real_cap;
+ }
+
+ //If there is no forward expansion, move objects
+ else{
+ //We will reuse insert code, so create a dummy input iterator
+ T *dummy_it(containers_detail::get_pointer(this->members_.m_start));
+ containers_detail::advanced_insert_aux_proxy<T, boost::move_iterator<T*>, T*>
+ proxy(::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+ //Backwards (and possibly forward) expansion
+ if(ret.second){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
+ this->priv_range_insert_expand_backwards
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(this->members_.m_start)
+ , 0
+ , proxy);
+ }
+ //New buffer
+ else{
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(this->members_.m_start)
+ , 0
+ , proxy);
+ }
+ }
+ }
+ }
+
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
+ {
+ if (&x != this){
+ this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size);
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear.
+ vector& operator=(BOOST_RV_REF(vector) x)
+ {
+ if (&x != this){
+ this->swap(x);
+ x.clear();
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const value_type& val)
+ { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InIt>
+ void assign(InIt first, InIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_assign_dispatch(first, last, Result());
+ }
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(const T &x);
+
+ //! <b>Effects</b>: Constructs a new element in the end of the vector
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+ #endif
+
+/*
+ void push_back(insert_const_ref_type x)
+ { return priv_push_back(x); }
+
+ #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ void push_back(T &x) { push_back(const_cast<const T &>(x)); }
+
+ template<class U>
+ typename containers_detail::enable_if_c
+ <!::boost::has_move_emulation_enabled<U>::value &&
+ containers_detail::is_same<T, U>::value
+ >::type
+ push_back(const U &u)
+ { return priv_push_back(u); }
+
+ #endif
+
+ //! <b>Effects</b>: Constructs a new element in the end of the vector
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(BOOST_RV_REF(T) x)
+ {
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)containers_detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(::boost::move(x));
+ ++this->members_.m_size;
+ }
+ else{
+ this->insert(this->cend(), ::boost::move(x));
+ }
+ }
+*/
+ //! <b>Effects</b>: Constructs a new element in the end of the vector
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+
+
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template<class ...Args>
+ void emplace_back(Args &&...args)
+ {
+ T* back_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)(back_pos))value_type(::boost::forward<Args>(args)...);
+ ++this->members_.m_size;
+ }
+ else{
+ typedef containers_detail::advanced_insert_aux_emplace<T, T*, Args...> type;
+ type &&proxy = type(::boost::forward<Args>(args)...);
+ priv_range_insert(back_pos, 1, proxy);
+ }
+ }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template<class ...Args>
+ iterator emplace(const_iterator position, Args && ...args)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ typedef containers_detail::advanced_insert_aux_emplace<T, T*, Args...> type;
+ type &&proxy = type(::boost::forward<Args>(args)...);
+ priv_range_insert(position.get_ptr(), 1, proxy);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ #else
+
+ void emplace_back()
+ {
+ T* back_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)(back_pos))value_type();
+ ++this->members_.m_size;
+ }
+ else{
+ containers_detail::advanced_insert_aux_emplace<value_type, T*> proxy;
+ priv_range_insert(back_pos, 1, proxy);
+ }
+ }
+
+ iterator emplace(const_iterator position)
+ {
+ size_type pos_n = position - cbegin();
+ containers_detail::advanced_insert_aux_emplace<value_type, T*> proxy;
+ priv_range_insert(containers_detail::get_pointer(position.get_ptr()), 1, proxy);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ T* back_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size; \
+ if (this->members_.m_size < this->members_.m_capacity){ \
+ new((void*)(back_pos))value_type \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ ++this->members_.m_size; \
+ } \
+ else{ \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_range_insert(back_pos, 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
+ { \
+ size_type pos_n = pos - cbegin(); \
+ containers_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
+ priv_range_insert(containers_detail::get_pointer(pos.get_ptr()), 1, proxy); \
+ return iterator(this->members_.m_start + pos_n); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! If this->allocator_type() != x.allocator_type()
+ //! allocators are also swapped.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ void swap(vector& x)
+ {
+ allocator_type &this_al = this->alloc(), &other_al = x.alloc();
+ //Just swap internals
+ containers_detail::do_swap(this->members_.m_start, x.members_.m_start);
+ containers_detail::do_swap(this->members_.m_size, x.members_.m_size);
+ containers_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity);
+
+ if (this_al != other_al){
+ containers_detail::do_swap(this_al, other_al);
+ }
+ }
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before position.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, const T &x);
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before position with mx's resources.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ iterator insert(const_iterator position, T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+ #endif
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last).
+ template <class InIt>
+ void insert(const_iterator pos, InIt first, InIt last)
+ {
+ //Dispatch depending on integer/iterator
+ const bool aux_boolean = containers_detail::is_convertible<InIt, size_type>::value;
+ typedef containers_detail::bool_<aux_boolean> Result;
+ this->priv_insert_dispatch(pos, first, last, Result());
+ }
+
+ //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert n copies of x before pos.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void insert(const_iterator p, size_type n, const T& x)
+ { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Removes the last element from the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ void pop_back()
+ {
+ //Destroy last element
+ --this->members_.m_size;
+ this->destroy(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ }
+
+ //! <b>Effects</b>: Erases the element at position pos.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the elements between pos and the
+ //! last element. Constant if pos is the last element.
+ iterator erase(const_iterator position)
+ {
+ T *pos = containers_detail::get_pointer(position.get_ptr());
+ T *beg = containers_detail::get_pointer(this->members_.m_start);
+ ::boost::move(pos + 1, beg + this->members_.m_size, pos);
+ --this->members_.m_size;
+ //Destroy last element
+ base_t::destroy(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ return iterator(position.get_ptr());
+ }
+
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last
+ //! plus linear to the elements between pos and the last element.
+ iterator erase(const_iterator first, const_iterator last)
+ {
+ if (first != last){ // worth doing, copy down over hole
+ T* end_pos = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ T* ptr = containers_detail::get_pointer(boost::move
+ (containers_detail::get_pointer(last.get_ptr())
+ ,end_pos
+ ,containers_detail::get_pointer(first.get_ptr())
+ ));
+ size_type destroyed = (end_pos - ptr);
+ this->destroy_n(ptr, destroyed);
+ this->members_.m_size -= destroyed;
+ }
+ return iterator(first.get_ptr());
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ pointer finish = this->members_.m_start + this->members_.m_size;
+ if (new_size < size()){
+ //Destroy last elements
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+ }
+ else{
+ //Insert new elements at the end
+ this->insert(const_iterator(finish), new_size - this->size(), x);
+ }
+ }
+
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ if (new_size < this->size()){
+ //Destroy last elements
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+ }
+ else{
+ size_type n = new_size - this->size();
+ this->reserve(new_size);
+ containers_detail::default_construct_aux_proxy<T, T*, size_type> proxy(n);
+ priv_range_insert(this->cend().get_ptr(), n, proxy);
+ }
+ }
+
+ //! <b>Effects</b>: Erases all the elements of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the vector.
+ void clear()
+ { this->prot_destroy_all(); }
+
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { priv_shrink_to_fit(alloc_version()); }
+
+ /// @cond
+
+ private:
+ iterator priv_insert(const_iterator position, const T &x)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position, (size_type)1, x);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ iterator priv_insert(const_iterator position, BOOST_RV_REF(T) x)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position
+ ,repeat_move_it(repeat_it(x, 1))
+ ,repeat_move_it(repeat_it()));
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ template <class U>
+ void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+ {
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)containers_detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(::boost::forward<U>(x));
+ ++this->members_.m_size;
+ }
+ else{
+ this->insert(this->cend(), ::boost::forward<U>(x));
+ }
+ }
+
+ void priv_shrink_to_fit(allocator_v1)
+ {
+ if(this->members_.m_capacity){
+ if(!size()){
+ this->prot_deallocate();
+ }
+ else{
+ //Allocate a new buffer.
+ size_type real_cap = 0;
+ std::pair<pointer, bool> ret =
+ this->allocation_command
+ (allocate_new, this->size(), this->size(), real_cap, this->members_.m_start);
+ if(real_cap < this->capacity()){
+ //We will reuse insert code, so create a dummy input iterator
+ T *dummy_it(containers_detail::get_pointer(this->members_.m_start));
+ containers_detail::advanced_insert_aux_proxy<T, boost::move_iterator<T*>, T*>
+ proxy(::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(this->members_.m_start)
+ , 0
+ , proxy);
+ }
+ else{
+ this->alloc().deallocate(ret.first, real_cap);
+ }
+ }
+ }
+ }
+
+ void priv_shrink_to_fit(allocator_v2)
+ {
+ if(this->members_.m_capacity){
+ if(!size()){
+ this->prot_deallocate();
+ }
+ else{
+ size_type received_size;
+ if(this->alloc().allocation_command
+ ( shrink_in_place | nothrow_allocation
+ , this->capacity(), this->size()
+ , received_size, this->members_.m_start).first){
+ this->members_.m_capacity = received_size;
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_shrink;
+ #endif
+ }
+ }
+ }
+ }
+
+ template <class FwdIt>
+ void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ if(first != last){
+ const size_type n = std::distance(first, last);
+ containers_detail::advanced_insert_aux_proxy<T, FwdIt, T*> proxy(first, last);
+ priv_range_insert(pos, n, proxy);
+ }
+ }
+
+ void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //Check if we have enough memory or try to expand current memory
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ bool same_buffer_start;
+ std::pair<pointer, bool> ret;
+ size_type real_cap = this->members_.m_capacity;
+
+ //Check if we already have room
+ if (n <= remaining){
+ same_buffer_start = true;
+ }
+ else{
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ size_type new_cap = this->next_capacity(n);
+ ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
+
+ //Check for forward expansion
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ this->members_.m_capacity = real_cap;
+ }
+ }
+
+ //If we had room or we have expanded forward
+ if (same_buffer_start){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->priv_range_insert_expand_forward
+ (containers_detail::get_pointer(pos), n, interf);
+ }
+ //Backwards (and possibly forward) expansion
+ else if(ret.second){
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
+ this->priv_range_insert_expand_backwards
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(pos)
+ , n
+ , interf);
+ }
+ //New buffer
+ else{
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( containers_detail::get_pointer(ret.first)
+ , real_cap
+ , containers_detail::get_pointer(pos)
+ , n
+ , interf);
+ }
+ }
+
+ void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //n can't be 0, because there is nothing to do in that case
+ if(!n) return;
+ //There is enough memory
+ T* old_finish = containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ const size_type elems_after = old_finish - pos;
+
+ if (elems_after > n){
+ //New elements can be just copied.
+ //Move to uninitialized memory last objects
+ ::boost::uninitialized_move(old_finish - n, old_finish, old_finish);
+ this->members_.m_size += n;
+ //Copy previous to last objects to the initialized end
+ boost::move_backward(pos, old_finish - n, old_finish);
+ //Insert new objects in the pos
+ interf.copy_all_to(pos);
+ }
+ else {
+ //The new elements don't fit in the [pos, end()) range. Copy
+ //to the beginning of the unallocated zone the last new elements.
+ interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
+ this->members_.m_size += n - elems_after;
+ //Copy old [pos, end()) elements to the uninitialized memory
+ ::boost::uninitialized_move
+ ( pos, old_finish, containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ this->members_.m_size += elems_after;
+ //Copy first new elements in pos
+ interf.copy_all_to(pos);
+ }
+ }
+
+ void priv_range_insert_new_allocation
+ (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //n can be zero, if we want to reallocate!
+ T *new_finish = new_start;
+ T *old_finish;
+ //Anti-exception rollbacks
+ typename value_traits::ArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
+ typename value_traits::ArrayDestructor constructed_values_destroyer(new_start, 0u);
+
+ //Initialize with [begin(), pos) old buffer
+ //the start of the new buffer
+ T *old_buffer = containers_detail::get_pointer(this->members_.m_start);
+ if(old_buffer){
+ new_finish = ::boost::uninitialized_move
+ (containers_detail::get_pointer(this->members_.m_start), pos, old_finish = new_finish);
+ constructed_values_destroyer.increment_size(new_finish - old_finish);
+ }
+ //Initialize new objects, starting from previous point
+ interf.uninitialized_copy_all_to(old_finish = new_finish);
+ new_finish += n;
+ constructed_values_destroyer.increment_size(new_finish - old_finish);
+ //Initialize from the rest of the old buffer,
+ //starting from previous point
+ if(old_buffer){
+ new_finish = ::boost::uninitialized_move
+ (pos, old_buffer + this->members_.m_size, new_finish);
+ //Destroy and deallocate old elements
+ //If there is allocated memory, destroy and deallocate
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(old_buffer, this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ }
+ this->members_.m_start = new_start;
+ this->members_.m_size = new_finish - new_start;
+ this->members_.m_capacity = new_cap;
+ //All construction successful, disable rollbacks
+ constructed_values_destroyer.release();
+ scoped_alloc.release();
+ }
+
+ void priv_range_insert_expand_backwards
+ (T* new_start, size_type new_capacity,
+ T* pos, const size_type n, advanced_insert_aux_int_t &interf)
+ {
+ //n can be zero to just expand capacity
+ //Backup old data
+ T* old_start = containers_detail::get_pointer(this->members_.m_start);
+ T* old_finish = old_start + this->members_.m_size;
+ size_type old_size = this->members_.m_size;
+
+ //We can have 8 possibilities:
+ const size_type elemsbefore = (size_type)(pos - old_start);
+ const size_type s_before = (size_type)(old_start - new_start);
+
+ //Update the vector buffer information to a safe state
+ this->members_.m_start = new_start;
+ this->members_.m_capacity = new_capacity;
+ this->members_.m_size = 0;
+
+ //If anything goes wrong, this object will destroy
+ //all the old objects to fulfill previous vector state
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
+ //Check if s_before is big enough to hold the beginning of old data + new data
+ if(difference_type(s_before) >= difference_type(elemsbefore + n)){
+ //Copy first old values before pos, after that the new objects
+ ::boost::uninitialized_move(old_start, pos, new_start);
+ this->members_.m_size = elemsbefore;
+ interf.uninitialized_copy_all_to(new_start + elemsbefore);
+ this->members_.m_size += n;
+ //Check if s_before is so big that even copying the old data + new data
+ //there is a gap between the new data and the old data
+ if(s_before >= (old_size + n)){
+ //Old situation:
+ // _________________________________________________________
+ //| raw_mem | old_begin | old_end |
+ //| __________________________________|___________|_________|
+ //
+ //New situation:
+ // _________________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|__________|_________|________________________|
+ //
+ //Now initialize the rest of memory with the last old values
+ ::boost::uninitialized_move
+ (pos, old_finish, new_start + elemsbefore + n);
+ //All new elements correctly constructed, avoid new element destruction
+ this->members_.m_size = old_size + n;
+ //Old values destroyed automatically with "old_values_destroyer"
+ //when "old_values_destroyer" goes out of scope unless the have trivial
+ //destructor after move.
+ if(value_traits::trivial_dctr_after_move)
+ old_values_destroyer.release();
+ }
+ //s_before is so big that divides old_end
+ else{
+ //Old situation:
+ // __________________________________________________
+ //| raw_mem | old_begin | old_end |
+ //| ___________________________|___________|_________|
+ //
+ //New situation:
+ // __________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|__________|_________|_________________|
+ //
+ //Now initialize the rest of memory with the last old values
+ //All new elements correctly constructed, avoid new element destruction
+ size_type raw_gap = s_before - (elemsbefore + n);
+ //Now initialize the rest of s_before memory with the
+ //first of elements after new values
+ ::boost::uninitialized_move(pos, pos + raw_gap, new_start + elemsbefore + n);
+ //Update size since we have a contiguous buffer
+ this->members_.m_size = old_size + s_before;
+ //All new elements correctly constructed, avoid old element destruction
+ old_values_destroyer.release();
+ //Now copy remaining last objects in the old buffer begin
+ T *to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
+ //Now destroy redundant elements except if they were moved and
+ //they have trivial destructor after move
+ size_type n_destroy = old_finish - to_destroy;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(to_destroy, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
+ }
+ else{
+ //Check if we have to do the insertion in two phases
+ //since maybe s_before is not big enough and
+ //the buffer was expanded both sides
+ //
+ //Old situation:
+ // _________________________________________________
+ //| raw_mem | old_begin + old_end | raw_mem |
+ //|_________|_____________________|_________________|
+ //
+ //New situation with do_after:
+ // _________________________________________________
+ //| old_begin + new + old_end | raw_mem |
+ //|___________________________________|_____________|
+ //
+ //New without do_after:
+ // _________________________________________________
+ //| old_begin + new + old_end | raw_mem |
+ //|____________________________|____________________|
+ //
+ bool do_after = n > s_before;
+
+ //Now we can have two situations: the raw_mem of the
+ //beginning divides the old_begin, or the new elements:
+ if (s_before <= elemsbefore) {
+ //The raw memory divides the old_begin group:
+ //
+ //If we need two phase construction (do_after)
+ //new group is divided in new = new_beg + new_end groups
+ //In this phase only new_beg will be inserted
+ //
+ //Old situation:
+ // _________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|_________|___________|_________|_________________|
+ //
+ //New situation with do_after(1):
+ //This is not definitive situation, the second phase
+ //will include
+ // _________________________________________________
+ //| old_begin | new_beg | old_end | raw_mem |
+ //|___________|_________|_________|_________________|
+ //
+ //New situation without do_after:
+ // _________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|_____|_________|_____________________|
+ //
+ //Copy the first part of old_begin to raw_mem
+ T *start_n = old_start + difference_type(s_before);
+ ::boost::uninitialized_move(old_start, start_n, new_start);
+ //The buffer is all constructed until old_end,
+ //release destroyer and update size
+ old_values_destroyer.release();
+ this->members_.m_size = old_size + s_before;
+ //Now copy the second part of old_begin overwriting himself
+ T* next = ::boost::move(start_n, pos, old_start);
+ if(do_after){
+ //Now copy the new_beg elements
+ interf.copy_some_and_update(next, s_before, true);
+ }
+ else{
+ //Now copy the all the new elements
+ interf.copy_all_to(next);
+ T* move_start = next + n;
+ //Now displace old_end elements
+ T* move_end = ::boost::move(pos, old_finish, move_start);
+ //Destroy remaining moved elements from old_end except if
+ //they have trivial destructor after being moved
+ difference_type n_destroy = s_before - n;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(move_end, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
+ }
+ else {
+ //If we have to expand both sides,
+ //we will play if the first new values so
+ //calculate the upper bound of new values
+
+ //The raw memory divides the new elements
+ //
+ //If we need two phase construction (do_after)
+ //new group is divided in new = new_beg + new_end groups
+ //In this phase only new_beg will be inserted
+ //
+ //Old situation:
+ // _______________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|_______________|___________|_________|_________________|
+ //
+ //New situation with do_after():
+ // ____________________________________________________
+ //| old_begin | new_beg | old_end | raw_mem |
+ //|___________|_______________|_________|______________|
+ //
+ //New situation without do_after:
+ // ______________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|_____|_________|__________________________|
+ //
+ //First copy whole old_begin and part of new to raw_mem
+ ::boost::uninitialized_move(old_start, pos, new_start);
+ this->members_.m_size = elemsbefore;
+
+ const size_type mid_n = difference_type(s_before) - elemsbefore;
+ interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
+ this->members_.m_size = old_size + s_before;
+ //The buffer is all constructed until old_end,
+ //release destroyer and update size
+ old_values_destroyer.release();
+
+ if(do_after){
+ //Copy new_beg part
+ interf.copy_some_and_update(old_start, s_before - mid_n, true);
+ }
+ else{
+ //Copy all new elements
+ interf.copy_all_to(old_start);
+ T* move_start = old_start + (n-mid_n);
+ //Displace old_end
+ T* move_end = ::boost::move(pos, old_finish, move_start);
+ //Destroy remaining moved elements from old_end except if they
+ //have trivial destructor after being moved
+ difference_type n_destroy = s_before - n;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(move_end, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
+ }
+
+ //This is only executed if two phase construction is needed
+ //This can be executed without exception handling since we
+ //have to just copy and append in raw memory and
+ //old_values_destroyer has been released in phase 1.
+ if(do_after){
+ //The raw memory divides the new elements
+ //
+ //Old situation:
+ // ______________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|______________|___________|____________|______________|
+ //
+ //New situation with do_after(1):
+ // _______________________________________________________
+ //| old_begin + new_beg | new_end |old_end | raw_mem |
+ //|__________________________|_________|________|_________|
+ //
+ //New situation with do_after(2):
+ // ______________________________________________________
+ //| old_begin + new | old_end |raw |
+ //|_______________________________________|_________|____|
+ //
+ const size_type n_after = n - s_before;
+ const difference_type elemsafter = old_size - elemsbefore;
+
+ //We can have two situations:
+ if (elemsafter > difference_type(n_after)){
+ //The raw_mem from end will divide displaced old_end
+ //
+ //Old situation:
+ // ______________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|______________|___________|____________|______________|
+ //
+ //New situation with do_after(1):
+ // _______________________________________________________
+ //| old_begin + new_beg | new_end |old_end | raw_mem |
+ //|__________________________|_________|________|_________|
+ //
+ //First copy the part of old_end raw_mem
+ T* finish_n = old_finish - difference_type(n_after);
+ ::boost::uninitialized_move(finish_n, old_finish, old_finish);
+ this->members_.m_size += n_after;
+ //Displace the rest of old_end to the new position
+ boost::move_backward(pos, finish_n, old_finish);
+ //Now overwrite with new_end
+ //The new_end part is [first + (n - n_after), last)
+ interf.copy_all_to(pos);
+ }
+ else {
+ //The raw_mem from end will divide new_end part
+ //
+ //Old situation:
+ // _____________________________________________________________
+ //| raw_mem | old_begin | old_end | raw_mem |
+ //|______________|___________|____________|_____________________|
+ //
+ //New situation with do_after(2):
+ // _____________________________________________________________
+ //| old_begin + new_beg | new_end |old_end | raw_mem |
+ //|__________________________|_______________|________|_________|
+ //
+ size_type mid_last_dist = n_after - elemsafter;
+ //First initialize data in raw memory
+ //The new_end part is [first + (n - n_after), last)
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_size += mid_last_dist;
+ ::boost::uninitialized_move(pos, old_finish, old_finish + mid_last_dist);
+ this->members_.m_size += n_after - mid_last_dist;
+ //Now copy the part of new_end over constructed elements
+ interf.copy_all_to(pos);
+ }
+ }
+ }
+ }
+
+ template <class InIt>
+ void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag)
+ {
+ for(;first != last; ++first){
+ this->insert(pos, ::boost::move(value_type(*first)));
+ }
+ }
+
+ template <class InIt>
+ void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag)
+ {
+ //Overwrite all elements we can from [first, last)
+ iterator cur = begin();
+ for ( ; first != last && cur != end(); ++cur, ++first){
+ *cur = *first;
+ }
+
+ if (first == last){
+ //There are no more elements in the sequence, erase remaining
+ this->erase(cur, cend());
+ }
+ else{
+ //There are more elements in the range, insert the remaining ones
+ this->insert(this->cend(), first, last);
+ }
+ }
+
+ template <class FwdIt>
+ void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type n = std::distance(first, last);
+ if(!n){
+ this->prot_destroy_all();
+ return;
+ }
+ //Check if we have enough memory or try to expand current memory
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ bool same_buffer_start;
+ std::pair<pointer, bool> ret;
+ size_type real_cap = this->members_.m_capacity;
+
+ if (n <= remaining){
+ same_buffer_start = true;
+ }
+ else{
+ //There is not enough memory, allocate a new buffer
+ size_type new_cap = this->next_capacity(n);
+ ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->size() + n, new_cap, real_cap, this->members_.m_start);
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ this->members_.m_capacity = real_cap;
+ }
+ }
+
+ if(same_buffer_start){
+ T *start = containers_detail::get_pointer(this->members_.m_start);
+ if (this->size() >= n){
+ //There is memory, but there are more old elements than new ones
+ //Overwrite old elements with new ones
+ std::copy(first, last, start);
+ //Destroy remaining old elements
+ this->destroy_n(start + n, this->members_.m_size - n);
+ this->members_.m_size = n;
+ }
+ else{
+ //There is memory, but there are less old elements than new ones
+ //First overwrite some old elements with new ones
+ FwdIt mid = first;
+ std::advance(mid, this->size());
+ // iG T *end = std::copy(first, mid, start);
+ T *end = std::copy(first, mid, start);
+ //Initialize the remaining new elements in the uninitialized memory
+ // iG std::uninitialized_copy(mid, last, end);
+ ::boost::uninitialized_copy_or_move(mid, last, end);
+ this->members_.m_size = n;
+ }
+ }
+ else if(!ret.second){
+ typename value_traits::ArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
+ // iG std::uninitialized_copy(first, last, containers_detail::get_pointer(ret.first));
+ ::boost::uninitialized_copy_or_move(first, last, containers_detail::get_pointer(ret.first));
+ scoped_alloc.release();
+ //Destroy and deallocate old buffer
+ if(this->members_.m_start != 0){
+ this->destroy_n(containers_detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ }
+ this->members_.m_start = ret.first;
+ this->members_.m_size = n;
+ this->members_.m_capacity = real_cap;
+ }
+ else{
+ //Backwards expansion
+ //If anything goes wrong, this object will destroy old objects
+ T *old_start = containers_detail::get_pointer(this->members_.m_start);
+ size_type old_size = this->members_.m_size;
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
+ //If something goes wrong size will be 0
+ //but holding the whole buffer
+ this->members_.m_size = 0;
+ this->members_.m_start = ret.first;
+ this->members_.m_capacity = real_cap;
+
+ //Backup old buffer data
+ size_type old_offset = old_start - containers_detail::get_pointer(ret.first);
+ size_type first_count = containers_detail::min_value(n, old_offset);
+
+ FwdIt mid = first;
+ std::advance(mid, first_count);
+ // iG std::uninitialized_copy(first, mid, containers_detail::get_pointer(ret.first));
+ ::boost::uninitialized_copy_or_move(first, mid, containers_detail::get_pointer(ret.first));
+
+ if(old_offset > n){
+ //All old elements will be destroyed by "old_values_destroyer"
+ this->members_.m_size = n;
+ }
+ else{
+ //We have constructed objects from the new begin until
+ //the old end so release the rollback destruction
+ old_values_destroyer.release();
+ this->members_.m_start = ret.first;
+ this->members_.m_size = first_count + old_size;
+ //Now overwrite the old values
+ size_type second_count = containers_detail::min_value(old_size, n - first_count);
+ FwdIt mid2 = mid;
+ std::advance(mid2, second_count);
+ // iG std::copy(mid, mid2, old_start);
+ std::copy(mid, mid2, old_start);
+
+ //Check if we still have to append elements in the
+ //uninitialized end
+ if(second_count == old_size){
+ // iG std::copy(mid2, last, old_start + old_size);
+ std::copy(mid2, last, old_start + old_size);
+ }
+ else{
+ //We have to destroy some old values
+ this->destroy_n
+ (old_start + second_count, old_size - second_count);
+ this->members_.m_size = n;
+ }
+ this->members_.m_size = n;
+ }
+ }
+ }
+
+ template <class Integer>
+ void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
+ { this->assign((size_type) n, (value_type)val); }
+
+ template <class InIt>
+ void priv_assign_dispatch(InIt first, InIt last, containers_detail::false_)
+ {
+ //Dispatch depending on integer/iterator
+ typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
+ this->priv_assign_aux(first, last, ItCat());
+ }
+
+ template <class Integer>
+ void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, containers_detail::true_)
+ { this->insert(pos, (size_type)n, (T)val); }
+
+ template <class InIt>
+ void priv_insert_dispatch(const_iterator pos, InIt first,
+ InIt last, containers_detail::false_)
+ {
+ //Dispatch depending on integer/iterator
+ typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
+ this->priv_range_insert(pos.get_ptr(), first, last, ItCat());
+ }
+
+ void priv_check_range(size_type n) const
+ {
+ //If n is out of range, throw an out_of_range exception
+ if (n >= size())
+ throw std::out_of_range("vector::at");
+ }
+
+ #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
+ public:
+ unsigned int num_expand_fwd;
+ unsigned int num_expand_bwd;
+ unsigned int num_shrink;
+ unsigned int num_alloc;
+ void reset_alloc_stats()
+ { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
+ #endif
+ /// @endcond
+};
+
+template <class T, class A>
+inline bool
+operator==(const vector<T, A>& x, const vector<T, A>& y)
+{
+ //Check first size and each element if needed
+ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class A>
+inline bool
+operator!=(const vector<T, A>& x, const vector<T, A>& y)
+{
+ //Check first size and each element if needed
+ return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class A>
+inline bool
+operator<(const vector<T, A>& x, const vector<T, A>& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template <class T, class A>
+inline void swap(vector<T, A>& x, vector<T, A>& y)
+{ x.swap(y); }
+
+}}
+
+/// @cond
+
+namespace boost {
+
+/*
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class A>
+struct has_trivial_destructor_after_move<boost::container::vector<T, A> >
+{
+ static const bool value = has_trivial_destructor<A>::value;
+};
+
+*/
+
+}
+
+/// @endcond
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_CONTAINERS_CONTAINERS_VECTOR_HPP
+
Modified: branches/release/boost/interprocess/allocators/adaptive_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/adaptive_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/adaptive_pool.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -28,7 +28,7 @@
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <memory>
#include <algorithm>
@@ -42,7 +42,7 @@
/// @cond
-namespace detail{
+namespace ipcdetail{
template < unsigned int Version
, class T
@@ -71,7 +71,7 @@
template <int dummy>
struct node_pool
{
- typedef detail::shared_adaptive_node_pool
+ typedef ipcdetail::shared_adaptive_node_pool
< SegmentManager, sizeof_value<T>::value, NodesPerBlock, MaxFreeBlocks, OverheadPercent> type;
static type *get(void *p)
@@ -88,9 +88,9 @@
typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
@@ -121,14 +121,14 @@
//!pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
adaptive_pool_base(segment_manager *segment_mngr)
- : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
+ : mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
//!Copy constructor from other adaptive_pool_base. Increments the reference
//!count of the associated node pool. Never throws
adaptive_pool_base(const adaptive_pool_base &other)
: mp_node_pool(other.get_node_pool())
{
- node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
+ node_pool<0>::get(ipcdetail::get_pointer(mp_node_pool))->inc_ref_count();
}
//!Assignment from other adaptive_pool_base
@@ -145,27 +145,27 @@
template<class T2>
adaptive_pool_base
(const adaptive_pool_base<Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
- : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
+ : mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
//!Destructor, removes node_pool_t from memory
//!if its reference count reaches to zero. Never throws
~adaptive_pool_base()
- { detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
+ { ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::get_pointer(mp_node_pool))); }
//!Returns a pointer to the node pool.
//!Never throws
void* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ { return ipcdetail::get_pointer(mp_node_pool); }
//!Returns the segment manager.
//!Never throws
segment_manager* get_segment_manager()const
- { return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
+ { return node_pool<0>::get(ipcdetail::get_pointer(mp_node_pool))->get_segment_manager(); }
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
- { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
+ { ipcdetail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
/// @cond
private:
@@ -204,7 +204,7 @@
>
{
public:
- typedef detail::adaptive_pool_base
+ typedef ipcdetail::adaptive_pool_base
< 1, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
template<class T2>
@@ -224,7 +224,7 @@
{}
};
-} //namespace detail{
+} //namespace ipcdetail{
/// @endcond
@@ -250,7 +250,7 @@
>
class adaptive_pool
/// @cond
- : public detail::adaptive_pool_base
+ : public ipcdetail::adaptive_pool_base
< 2
, T
, SegmentManager
@@ -262,7 +262,7 @@
{
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
- typedef detail::adaptive_pool_base
+ typedef ipcdetail::adaptive_pool_base
< 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
public:
typedef boost::interprocess::version_type<adaptive_pool, 2> version;
@@ -290,9 +290,9 @@
typedef implementation_defined::pointer pointer;
typedef implementation_defined::const_pointer const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
Modified: branches/release/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/allocator.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -22,7 +22,7 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/containers/allocation_type.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/containers/version_type.hpp>
@@ -91,9 +91,9 @@
<cvoid_ptr, T>::type pointer;
typedef typename boost::
pointer_to_other<pointer, const T>::type const_pointer;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
@@ -118,7 +118,7 @@
//!Returns the segment manager.
//!Never throws
segment_manager* get_segment_manager()const
- { return detail::get_pointer(mp_mngr); }
+ { return ipcdetail::get_pointer(mp_mngr); }
//!Constructor from the segment manager.
//!Never throws
@@ -149,7 +149,7 @@
//!Deallocates memory previously allocated.
//!Never throws
void deallocate(const pointer &ptr, size_type)
- { mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
+ { mp_mngr->deallocate((void*)ipcdetail::get_pointer(ptr)); }
//!Returns the number of elements that could be allocated.
//!Never throws
@@ -159,14 +159,14 @@
//!Swap segment manager. Does not throw. If each allocator is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
- { detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
+ { ipcdetail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold. This size only works for memory allocated with
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const
{
- return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T);
+ return (size_type)mp_mngr->size(ipcdetail::get_pointer(p))/sizeof(T);
}
std::pair<pointer, bool>
@@ -176,7 +176,7 @@
size_type &received_size, const pointer &reuse = 0)
{
return mp_mngr->allocation_command
- (command, limit_size, preferred_size, received_size, detail::get_pointer(reuse));
+ (command, limit_size, preferred_size, received_size, ipcdetail::get_pointer(reuse));
}
//!Allocates many elements of size elem_size in a contiguous block
@@ -255,12 +255,12 @@
//!Copy construct an object
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v)
- { new((void*)detail::get_pointer(ptr)) value_type(v); }
+ { new((void*)ipcdetail::get_pointer(ptr)) value_type(v); }
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr)
- { new((void*)detail::get_pointer(ptr)) value_type; }
+ { new((void*)ipcdetail::get_pointer(ptr)) value_type; }
//!Destroys object. Throws if object's
//!destructor throws
Modified: branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -35,7 +35,7 @@
/// @cond
-namespace detail {
+namespace ipcdetail {
template < class T
, class SegmentManager
@@ -44,9 +44,9 @@
, unsigned char OverheadPercent = 5
>
class cached_adaptive_pool_v1
- : public detail::cached_allocator_impl
+ : public ipcdetail::cached_allocator_impl
< T
- , detail::shared_adaptive_node_pool
+ , ipcdetail::shared_adaptive_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -56,9 +56,9 @@
, 1>
{
public:
- typedef detail::cached_allocator_impl
+ typedef ipcdetail::cached_allocator_impl
< T
- , detail::shared_adaptive_node_pool
+ , ipcdetail::shared_adaptive_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -89,7 +89,7 @@
{}
};
-} //namespace detail{
+} //namespace ipcdetail{
/// @endcond
@@ -118,9 +118,9 @@
>
class cached_adaptive_pool
/// @cond
- : public detail::cached_allocator_impl
+ : public ipcdetail::cached_allocator_impl
< T
- , detail::shared_adaptive_node_pool
+ , ipcdetail::shared_adaptive_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -133,9 +133,9 @@
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
- typedef detail::cached_allocator_impl
+ typedef ipcdetail::cached_allocator_impl
< T
- , detail::shared_adaptive_node_pool
+ , ipcdetail::shared_adaptive_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -172,9 +172,9 @@
typedef implementation_defined::pointer pointer;
typedef implementation_defined::const_pointer const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
Modified: branches/release/boost/interprocess/allocators/cached_node_allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/cached_node_allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/cached_node_allocator.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -36,16 +36,16 @@
/// @cond
-namespace detail {
+namespace ipcdetail {
template < class T
, class SegmentManager
, std::size_t NodesPerBlock = 64
>
class cached_node_allocator_v1
- : public detail::cached_allocator_impl
+ : public ipcdetail::cached_allocator_impl
< T
- , detail::shared_node_pool
+ , ipcdetail::shared_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -53,9 +53,9 @@
, 1>
{
public:
- typedef detail::cached_allocator_impl
+ typedef ipcdetail::cached_allocator_impl
< T
- , detail::shared_node_pool
+ , ipcdetail::shared_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -84,7 +84,7 @@
{}
};
-} //namespace detail{
+} //namespace ipcdetail{
/// @endcond
@@ -94,9 +94,9 @@
>
class cached_node_allocator
/// @cond
- : public detail::cached_allocator_impl
+ : public ipcdetail::cached_allocator_impl
< T
- , detail::shared_node_pool
+ , ipcdetail::shared_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -107,9 +107,9 @@
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
public:
- typedef detail::cached_allocator_impl
+ typedef ipcdetail::cached_allocator_impl
< T
- , detail::shared_node_pool
+ , ipcdetail::shared_node_pool
< SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -144,9 +144,9 @@
typedef implementation_defined::pointer pointer;
typedef implementation_defined::const_pointer const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename SegmentManager::size_type size_type;
typedef typename SegmentManager::difference_type difference_type;
Modified: branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -28,7 +28,7 @@
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <cstddef>
#include <boost/config/no_tr1/cmath.hpp>
-#include <boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp>
+#include <boost/container/detail/adaptive_node_pool_impl.hpp>
#include <boost/assert.hpp>
//!\file
@@ -36,7 +36,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
template< class SegmentManager
, std::size_t NodeSize
@@ -85,12 +85,12 @@
, unsigned char OverheadPercent
>
class shared_adaptive_node_pool
- : public detail::shared_pool_impl
+ : public ipcdetail::shared_pool_impl
< private_adaptive_node_pool
<SegmentManager, NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
>
{
- typedef detail::shared_pool_impl
+ typedef ipcdetail::shared_pool_impl
< private_adaptive_node_pool
<SegmentManager, NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
> base_t;
@@ -100,7 +100,7 @@
{}
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/allocators/detail/allocator_common.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/allocator_common.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/allocator_common.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -25,7 +25,7 @@
#include <boost/interprocess/exceptions.hpp> //bad_alloc
#include <boost/interprocess/sync/scoped_lock.hpp> //scoped_lock
#include <boost/interprocess/containers/allocation_type.hpp> //boost::interprocess::allocation_type
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/interprocess/detail/segment_manager_helper.hpp>
#include <algorithm> //std::swap
@@ -67,7 +67,7 @@
static const std::size_t value = sizeof(void*);
};
-namespace detail {
+namespace ipcdetail {
//!Object function that creates the node allocator if it is not created and
//!increments reference count if it is already created
@@ -99,7 +99,7 @@
template<class NodePool>
inline NodePool *get_or_create_node_pool(typename NodePool::segment_manager *mgnr)
{
- detail::get_or_create_node_pool_func<NodePool> func(mgnr);
+ ipcdetail::get_or_create_node_pool_func<NodePool> func(mgnr);
mgnr->atomic_func(func);
return func.mp_node_pool;
}
@@ -173,11 +173,11 @@
~cache_impl()
{
this->deallocate_all_cached_nodes();
- detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool));
+ ipcdetail::destroy_node_pool_if_last_link(ipcdetail::get_pointer(mp_node_pool));
}
NodePool *get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ { return ipcdetail::get_pointer(mp_node_pool); }
segment_manager *get_segment_manager() const
{ return mp_node_pool->get_segment_manager(); }
@@ -191,7 +191,7 @@
if(m_cached_nodes.empty()){
m_cached_nodes = mp_node_pool->allocate_nodes(m_max_cached_nodes/2);
}
- void *ret = detail::get_pointer(m_cached_nodes.front());
+ void *ret = ipcdetail::get_pointer(m_cached_nodes.front());
m_cached_nodes.pop_front();
return ret;
}
@@ -203,7 +203,7 @@
BOOST_TRY{
//If don't have any cached node, we have to get a new list of free nodes from the pool
while(!m_cached_nodes.empty() && count--){
- void *ret = detail::get_pointer(m_cached_nodes.front());
+ void *ret = ipcdetail::get_pointer(m_cached_nodes.front());
m_cached_nodes.pop_front();
chain.push_back(ret);
++allocated;
@@ -296,9 +296,9 @@
public:
void swap(cache_impl &other)
{
- detail::do_swap(mp_node_pool, other.mp_node_pool);
+ ipcdetail::do_swap(mp_node_pool, other.mp_node_pool);
m_cached_nodes.swap(other.m_cached_nodes);
- detail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
+ ipcdetail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
}
};
@@ -318,9 +318,9 @@
typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename SegmentManager::size_type size_type;
typedef typename SegmentManager::difference_type difference_type;
@@ -334,7 +334,7 @@
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const
{
- return (size_type)this->derived()->get_segment_manager()->size(detail::get_pointer(p))/sizeof(T);
+ return (size_type)this->derived()->get_segment_manager()->size(ipcdetail::get_pointer(p))/sizeof(T);
}
std::pair<pointer, bool>
@@ -344,7 +344,7 @@
size_type &received_size, const pointer &reuse = 0)
{
return this->derived()->get_segment_manager()->allocation_command
- (command, limit_size, preferred_size, received_size, detail::get_pointer(reuse));
+ (command, limit_size, preferred_size, received_size, ipcdetail::get_pointer(reuse));
}
//!Allocates many elements of size elem_size in a contiguous block
@@ -393,12 +393,12 @@
//!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr)
- { new((void*)detail::get_pointer(ptr)) value_type; }
+ { new((void*)ipcdetail::get_pointer(ptr)) value_type; }
//!Copy construct an object
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v)
- { new((void*)detail::get_pointer(ptr)) value_type(v); }
+ { new((void*)ipcdetail::get_pointer(ptr)) value_type(v); }
//!Destroys object. Throws if object's
//!destructor throws
@@ -429,9 +429,9 @@
typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename SegmentManager::size_type size_type;
typedef typename SegmentManager::difference_type difference_type;
@@ -472,9 +472,9 @@
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
if(Version == 1 && count == 1)
- pool->deallocate_node(detail::get_pointer(ptr));
+ pool->deallocate_node(ipcdetail::get_pointer(ptr));
else
- pool->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
+ pool->get_segment_manager()->deallocate((void*)ipcdetail::get_pointer(ptr));
}
//!Allocates just one object. Memory allocated with this function
@@ -507,7 +507,7 @@
{
typedef typename node_pool<0>::type node_pool_t;
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
- pool->deallocate_node(detail::get_pointer(p));
+ pool->deallocate_node(ipcdetail::get_pointer(p));
}
//!Allocates many elements of size == 1 in a contiguous block
@@ -618,10 +618,10 @@
{
(void)count;
if(Version == 1 && count == 1){
- m_cache.cached_deallocation(detail::get_pointer(ptr));
+ m_cache.cached_deallocation(ipcdetail::get_pointer(ptr));
}
else{
- this->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
+ this->get_segment_manager()->deallocate((void*)ipcdetail::get_pointer(ptr));
}
}
@@ -644,7 +644,7 @@
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &p)
- { this->m_cache.cached_deallocation(detail::get_pointer(p)); }
+ { this->m_cache.cached_deallocation(ipcdetail::get_pointer(p)); }
//!Allocates many elements of size == 1 in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -850,7 +850,7 @@
} m_header;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/allocators/detail/node_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/node_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/node_pool.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -24,7 +24,7 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
-#include <boost/interprocess/containers/container/detail/node_pool_impl.hpp>
+#include <boost/container/detail/node_pool_impl.hpp>
#include <cstddef>
@@ -33,7 +33,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
@@ -86,12 +86,12 @@
, std::size_t NodesPerBlock
>
class shared_node_pool
- : public detail::shared_pool_impl
+ : public ipcdetail::shared_pool_impl
< private_node_pool
<SegmentManager, NodeSize, NodesPerBlock>
>
{
- typedef detail::shared_pool_impl
+ typedef ipcdetail::shared_pool_impl
< private_node_pool
<SegmentManager, NodeSize, NodesPerBlock>
> base_t;
@@ -101,7 +101,7 @@
{}
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/allocators/detail/node_tools.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/node_tools.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/node_tools.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -22,7 +22,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
template<class VoidPointer>
@@ -41,7 +41,7 @@
<node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/allocators/node_allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/node_allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/node_allocator.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -26,7 +26,7 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/allocators/detail/node_pool.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <memory>
@@ -41,7 +41,7 @@
/// @cond
-namespace detail{
+namespace ipcdetail{
template < unsigned int Version
, class T
@@ -68,7 +68,7 @@
template <int dummy>
struct node_pool
{
- typedef detail::shared_node_pool
+ typedef ipcdetail::shared_node_pool
< SegmentManager, sizeof_value<T>::value, NodesPerBlock> type;
static type *get(void *p)
@@ -85,9 +85,9 @@
typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
@@ -120,14 +120,14 @@
//!pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
node_allocator_base(segment_manager *segment_mngr)
- : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
+ : mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
//!Copy constructor from other node_allocator_base. Increments the reference
//!count of the associated node pool. Never throws
node_allocator_base(const node_allocator_base &other)
: mp_node_pool(other.get_node_pool())
{
- node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
+ node_pool<0>::get(ipcdetail::get_pointer(mp_node_pool))->inc_ref_count();
}
//!Copy constructor from related node_allocator_base. If not present, constructs
@@ -136,7 +136,7 @@
template<class T2>
node_allocator_base
(const node_allocator_base<Version, T2, SegmentManager, NodesPerBlock> &other)
- : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
+ : mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
//!Assignment from other node_allocator_base
node_allocator_base& operator=(const node_allocator_base &other)
@@ -149,22 +149,22 @@
//!Destructor, removes node_pool_t from memory
//!if its reference count reaches to zero. Never throws
~node_allocator_base()
- { detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
+ { ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::get_pointer(mp_node_pool))); }
//!Returns a pointer to the node pool.
//!Never throws
void* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ { return ipcdetail::get_pointer(mp_node_pool); }
//!Returns the segment manager.
//!Never throws
segment_manager* get_segment_manager()const
- { return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
+ { return node_pool<0>::get(ipcdetail::get_pointer(mp_node_pool))->get_segment_manager(); }
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
- { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
+ { ipcdetail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
/// @cond
private:
@@ -199,7 +199,7 @@
>
{
public:
- typedef detail::node_allocator_base
+ typedef ipcdetail::node_allocator_base
< 1, T, SegmentManager, NodesPerBlock> base_t;
template<class T2>
@@ -219,7 +219,7 @@
{}
};
-} //namespace detail{
+} //namespace ipcdetail{
/// @endcond
@@ -237,7 +237,7 @@
>
class node_allocator
/// @cond
- : public detail::node_allocator_base
+ : public ipcdetail::node_allocator_base
< 2
, T
, SegmentManager
@@ -247,7 +247,7 @@
{
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
- typedef detail::node_allocator_base
+ typedef ipcdetail::node_allocator_base
< 2, T, SegmentManager, NodesPerBlock> base_t;
public:
typedef boost::interprocess::version_type<node_allocator, 2> version;
@@ -275,9 +275,9 @@
typedef implementation_defined::pointer pointer;
typedef implementation_defined::const_pointer const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
Modified: branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -24,7 +24,7 @@
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/workaround.hpp>
@@ -40,7 +40,7 @@
/// @cond
-namespace detail {
+namespace ipcdetail {
template < unsigned int Version
, class T
@@ -68,7 +68,7 @@
typedef private_adaptive_pool_base
< Version, T, SegmentManager, NodesPerBlock
, MaxFreeBlocks, OverheadPercent> self_t;
- typedef detail::private_adaptive_node_pool
+ typedef ipcdetail::private_adaptive_node_pool
<SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -86,9 +86,9 @@
typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::size_type difference_type;
@@ -110,7 +110,7 @@
template <int dummy>
struct node_pool
{
- typedef detail::private_adaptive_node_pool
+ typedef ipcdetail::private_adaptive_node_pool
<SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -203,7 +203,7 @@
>
{
public:
- typedef detail::private_adaptive_pool_base
+ typedef ipcdetail::private_adaptive_pool_base
< 1, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
template<class T2>
@@ -223,7 +223,7 @@
{}
};
-} //namespace detail {
+} //namespace ipcdetail {
/// @endcond
@@ -248,7 +248,7 @@
>
class private_adaptive_pool
/// @cond
- : public detail::private_adaptive_pool_base
+ : public ipcdetail::private_adaptive_pool_base
< 2
, T
, SegmentManager
@@ -260,7 +260,7 @@
{
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
- typedef detail::private_adaptive_pool_base
+ typedef ipcdetail::private_adaptive_pool_base
< 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
public:
typedef boost::interprocess::version_type<private_adaptive_pool, 2> version;
@@ -289,9 +289,9 @@
typedef implementation_defined::pointer pointer;
typedef implementation_defined::const_pointer const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
Modified: branches/release/boost/interprocess/allocators/private_node_allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/private_node_allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/private_node_allocator.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -24,7 +24,7 @@
#include <boost/assert.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/interprocess/allocators/detail/node_pool.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/workaround.hpp>
@@ -40,7 +40,7 @@
/// @cond
-namespace detail {
+namespace ipcdetail {
template < unsigned int Version
, class T
@@ -64,7 +64,7 @@
private:
typedef private_node_allocator_base
< Version, T, SegmentManager, NodesPerBlock> self_t;
- typedef detail::private_node_pool
+ typedef ipcdetail::private_node_pool
<SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -80,9 +80,9 @@
typedef typename boost::
pointer_to_other<void_pointer, const T>::type const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
@@ -103,7 +103,7 @@
template <int dummy>
struct node_pool
{
- typedef detail::private_node_pool
+ typedef ipcdetail::private_node_pool
<SegmentManager
, sizeof_value<T>::value
, NodesPerBlock
@@ -190,7 +190,7 @@
>
{
public:
- typedef detail::private_node_allocator_base
+ typedef ipcdetail::private_node_allocator_base
< 1, T, SegmentManager, NodesPerBlock> base_t;
template<class T2>
@@ -210,7 +210,7 @@
{}
};
-} //namespace detail {
+} //namespace ipcdetail {
/// @endcond
@@ -226,7 +226,7 @@
>
class private_node_allocator
/// @cond
- : public detail::private_node_allocator_base
+ : public ipcdetail::private_node_allocator_base
< 2
, T
, SegmentManager
@@ -236,7 +236,7 @@
{
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
- typedef detail::private_node_allocator_base
+ typedef ipcdetail::private_node_allocator_base
< 2, T, SegmentManager, NodesPerBlock> base_t;
public:
typedef boost::interprocess::version_type<private_node_allocator, 2> version;
@@ -265,9 +265,9 @@
typedef implementation_defined::pointer pointer;
typedef implementation_defined::const_pointer const_pointer;
typedef T value_type;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename segment_manager::size_type size_type;
typedef typename segment_manage::difference_type difference_type;
Modified: branches/release/boost/interprocess/anonymous_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/anonymous_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/anonymous_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -37,7 +37,7 @@
/// @cond
-namespace detail{
+namespace ipcdetail{
class raw_mapped_region_creator
{
@@ -101,7 +101,7 @@
if(fd != -1)
close(fd);
- return detail::raw_mapped_region_creator::create_posix_mapped_region(address, 0, size);
+ return ipcdetail::raw_mapped_region_creator::create_posix_mapped_region(address, 0, size);
}
#else
{
Modified: branches/release/boost/interprocess/containers/allocation_type.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/allocation_type.hpp (original)
+++ branches/release/boost/interprocess/containers/allocation_type.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/detail/allocation_type.hpp>
+#include <boost/container/detail/allocation_type.hpp>
namespace boost {
namespace interprocess {
Modified: branches/release/boost/interprocess/containers/containers_fwd.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/containers_fwd.hpp (original)
+++ branches/release/boost/interprocess/containers/containers_fwd.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -22,7 +22,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/container_fwd.hpp>
+#include <boost/container/container_fwd.hpp>
namespace boost {
namespace interprocess {
Modified: branches/release/boost/interprocess/containers/deque.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/deque.hpp (original)
+++ branches/release/boost/interprocess/containers/deque.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/deque.hpp>
+#include <boost/container/deque.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/flat_map.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/flat_map.hpp (original)
+++ branches/release/boost/interprocess/containers/flat_map.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/flat_map.hpp>
+#include <boost/container/flat_map.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/flat_set.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/flat_set.hpp (original)
+++ branches/release/boost/interprocess/containers/flat_set.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/flat_set.hpp>
+#include <boost/container/flat_set.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/list.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/list.hpp (original)
+++ branches/release/boost/interprocess/containers/list.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/list.hpp>
+#include <boost/container/list.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/map.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/map.hpp (original)
+++ branches/release/boost/interprocess/containers/map.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/map.hpp>
+#include <boost/container/map.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/pair.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/pair.hpp (original)
+++ branches/release/boost/interprocess/containers/pair.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/detail/pair.hpp>
+#include <boost/container/detail/pair.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/set.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/set.hpp (original)
+++ branches/release/boost/interprocess/containers/set.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/set.hpp>
+#include <boost/container/set.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/slist.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/slist.hpp (original)
+++ branches/release/boost/interprocess/containers/slist.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/slist.hpp>
+#include <boost/container/slist.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/stable_vector.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/stable_vector.hpp (original)
+++ branches/release/boost/interprocess/containers/stable_vector.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/stable_vector.hpp>
+#include <boost/container/stable_vector.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/string.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/string.hpp (original)
+++ branches/release/boost/interprocess/containers/string.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/string.hpp>
+#include <boost/container/string.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/vector.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/vector.hpp (original)
+++ branches/release/boost/interprocess/containers/vector.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/vector.hpp>
+#include <boost/container/vector.hpp>
#include <boost/interprocess/containers/containers_fwd.hpp>
namespace boost {
Modified: branches/release/boost/interprocess/containers/version_type.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/version_type.hpp (original)
+++ branches/release/boost/interprocess/containers/version_type.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -16,7 +16,7 @@
#endif
#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/containers/container/detail/version_type.hpp>
+#include <boost/container/detail/version_type.hpp>
namespace boost {
namespace interprocess {
Modified: branches/release/boost/interprocess/creation_tags.hpp
==============================================================================
--- branches/release/boost/interprocess/creation_tags.hpp (original)
+++ branches/release/boost/interprocess/creation_tags.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -61,12 +61,12 @@
//!be only opened for reading
static const open_copy_on_write_t open_copy_on_write = open_copy_on_write_t();
-namespace detail {
+namespace ipcdetail {
enum create_enum_t
{ DoCreate, DoOpen, DoOpenOrCreate };
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/atomic.hpp (original)
+++ branches/release/boost/interprocess/detail/atomic.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -21,7 +21,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
//! Atomically increment an boost::uint32_t by 1
//! "mem": pointer to the object
@@ -45,7 +45,7 @@
inline boost::uint32_t atomic_cas32
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp);
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -55,7 +55,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
//! Atomically decrement an boost::uint32_t by 1
//! "mem": pointer to the atomic value
@@ -89,7 +89,7 @@
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
{ return winapi::interlocked_compare_exchange(reinterpret_cast<volatile long*>(mem), with, cmp); }
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -97,7 +97,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
//! Compare an boost::uint32_t's value with "cmp".
//! If they are the same swap the value with "with"
@@ -190,7 +190,7 @@
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
{ *mem = val; }
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -198,7 +198,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
//! Atomically add 'val' to an boost::uint32_t
//! "mem": pointer to the object
@@ -271,7 +271,7 @@
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
{ *mem = val; }
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -279,7 +279,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
//! Atomically add 'val' to an boost::uint32_t
//! "mem": pointer to the object
@@ -321,7 +321,7 @@
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
{ *mem = val; }
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -331,7 +331,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
//! Atomically add 'val' to an boost::uint32_t
//! "mem": pointer to the object
@@ -372,7 +372,7 @@
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
{ *mem = val; }
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -383,7 +383,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
//! Atomically decrement a uint32_t by 1
//! "mem": pointer to the atomic value
@@ -467,7 +467,7 @@
mem, with, cmp);
}
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
@@ -477,7 +477,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
//all the functions with casts
@@ -559,7 +559,7 @@
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
{ *mem = val; }
-} //namespace detail
+} //namespace ipcdetail
} //namespace interprocess
} //namespace boost
@@ -571,7 +571,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
inline bool atomic_add_unless32
(volatile boost::uint32_t *mem, boost::uint32_t value, boost::uint32_t unless_this)
@@ -583,7 +583,7 @@
return c != unless_this;
}
-} //namespace detail
+} //namespace ipcdetail
} //namespace interprocess
} //namespace boost
Modified: branches/release/boost/interprocess/detail/cast_tags.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/cast_tags.hpp (original)
+++ branches/release/boost/interprocess/detail/cast_tags.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -14,14 +14,14 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-namespace boost { namespace interprocess { namespace detail {
+namespace boost { namespace interprocess { namespace ipcdetail {
struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct reinterpret_cast_tag {};
-}}} //namespace boost { namespace interprocess { namespace detail {
+}}} //namespace boost { namespace interprocess { namespace ipcdetail {
#include <boost/interprocess/detail/config_end.hpp>
Modified: branches/release/boost/interprocess/detail/file_wrapper.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/file_wrapper.hpp (original)
+++ branches/release/boost/interprocess/detail/file_wrapper.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -20,7 +20,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
class file_wrapper
{
@@ -36,24 +36,24 @@
//!Creates a file object with name "name" and mode "mode", with the access mode "mode"
//!If the file previously exists, throws an error.
file_wrapper(create_only_t, const char *name, mode_t mode, const permissions &perm = permissions())
- { this->priv_open_or_create(detail::DoCreate, name, mode, perm); }
+ { this->priv_open_or_create(ipcdetail::DoCreate, name, mode, perm); }
//!Tries to create a file with name "name" and mode "mode", with the
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
//!Otherwise throws an error.
file_wrapper(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
- { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode, perm); }
+ { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
//!Tries to open a file with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
file_wrapper(open_only_t, const char *name, mode_t mode)
- { this->priv_open_or_create(detail::DoOpen, name, mode, permissions()); }
+ { this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
//!Moves the ownership of "moved"'s file to *this.
//!After the call, "moved" does not represent any file.
//!Does not throw
file_wrapper(BOOST_RV_REF(file_wrapper) moved)
- : m_handle(file_handle_t(detail::invalid_file()))
+ : m_handle(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s file to *this.
@@ -101,7 +101,7 @@
//!Closes a previously opened file mapping. Never throws.
void priv_close();
//!Closes a previously opened file mapping. Never throws.
- bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
+ bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
file_handle_t m_handle;
mode_t m_mode;
@@ -109,7 +109,7 @@
};
inline file_wrapper::file_wrapper()
- : m_handle(file_handle_t(detail::invalid_file()))
+ : m_handle(file_handle_t(ipcdetail::invalid_file()))
{}
inline file_wrapper::~file_wrapper()
@@ -135,7 +135,7 @@
{ return m_mode; }
inline bool file_wrapper::priv_open_or_create
- (detail::create_enum_t type,
+ (ipcdetail::create_enum_t type,
const char *filename,
mode_t mode,
const permissions &perm = permissions())
@@ -149,13 +149,13 @@
//Open file existing native API to obtain the handle
switch(type){
- case detail::DoOpen:
+ case ipcdetail::DoOpen:
m_handle = open_existing_file(filename, mode);
break;
- case detail::DoCreate:
+ case ipcdetail::DoCreate:
m_handle = create_new_file(filename, mode, perm);
break;
- case detail::DoOpenOrCreate:
+ case ipcdetail::DoOpenOrCreate:
m_handle = create_or_open_file(filename, mode, perm);
break;
default:
@@ -193,7 +193,7 @@
}
}
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/in_place_interface.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/in_place_interface.hpp (original)
+++ branches/release/boost/interprocess/detail/in_place_interface.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -26,7 +26,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
struct in_place_interface
{
@@ -66,7 +66,7 @@
}
}
-} //namespace boost { namespace interprocess { namespace detail {
+} //namespace boost { namespace interprocess { namespace ipcdetail {
#include <boost/interprocess/detail/config_end.hpp>
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -51,7 +51,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
namespace file_locking_helpers {
@@ -823,7 +823,7 @@
break;
}
else if(previous_module_singleton_initialized == Initializing){
- detail::thread_yield();
+ ipcdetail::thread_yield();
}
else{
//This can't be happening!
@@ -1026,7 +1026,7 @@
{};
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
Modified: branches/release/boost/interprocess/detail/interprocess_tester.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/interprocess_tester.hpp (original)
+++ branches/release/boost/interprocess/detail/interprocess_tester.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -13,7 +13,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
class interprocess_tester
{
@@ -23,7 +23,7 @@
{ t.dont_close_on_destruction(); }
};
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
Modified: branches/release/boost/interprocess/detail/intersegment_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/intersegment_ptr.hpp (original)
+++ branches/release/boost/interprocess/detail/intersegment_ptr.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -153,12 +153,12 @@
{
if(orig_size < align)
orig_size = align;
- orig_size = detail::get_rounded_size_po2(orig_size, align);
- pow = detail::floor_log2(orig_size);
+ orig_size = ipcdetail::get_rounded_size_po2(orig_size, align);
+ pow = ipcdetail::floor_log2(orig_size);
std::size_t low_size = (std::size_t(1) << pow);
std::size_t diff = orig_size - low_size;
BOOST_ASSERT(pow >= frc_size_bits);
- std::size_t rounded = detail::get_rounded_size_po2
+ std::size_t rounded = ipcdetail::get_rounded_size_po2
(diff, (std::size_t)(1u << (pow - frc_size_bits)));
if(rounded == low_size){
++pow;
@@ -604,7 +604,7 @@
public:
typedef T * pointer;
- typedef typename detail::add_reference<T>::type reference;
+ typedef typename ipcdetail::add_reference<T>::type reference;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
@@ -635,25 +635,25 @@
//!Emulates static_cast operator.
//!Never throws.
template<class U>
- intersegment_ptr(const intersegment_ptr<U> &r, detail::static_cast_tag)
+ intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::static_cast_tag)
{ base_t::set_from_pointer(static_cast<T*>(r.get())); }
//!Emulates const_cast operator.
//!Never throws.
template<class U>
- intersegment_ptr(const intersegment_ptr<U> &r, detail::const_cast_tag)
+ intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::const_cast_tag)
{ base_t::set_from_pointer(const_cast<T*>(r.get())); }
//!Emulates dynamic_cast operator.
//!Never throws.
template<class U>
- intersegment_ptr(const intersegment_ptr<U> &r, detail::dynamic_cast_tag)
+ intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::dynamic_cast_tag)
{ base_t::set_from_pointer(dynamic_cast<T*>(r.get())); }
//!Emulates reinterpret_cast operator.
//!Never throws.
template<class U>
- intersegment_ptr(const intersegment_ptr<U> &r, detail::reinterpret_cast_tag)
+ intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::reinterpret_cast_tag)
{ base_t::set_from_pointer(reinterpret_cast<T*>(r.get())); }
//!Obtains raw pointer from offset.
@@ -875,25 +875,25 @@
//!Never throws.
template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> static_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
-{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::static_cast_tag()); }
+{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::static_cast_tag()); }
//!Simulation of const_cast between pointers.
//!Never throws.
template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> const_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
-{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::const_cast_tag()); }
+{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::const_cast_tag()); }
//!Simulation of dynamic_cast between pointers.
//!Never throws.
template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> dynamic_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
-{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::dynamic_cast_tag()); }
+{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::dynamic_cast_tag()); }
//!Simulation of reinterpret_cast between pointers.
//!Never throws.
template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> reinterpret_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
-{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::reinterpret_cast_tag()); }
+{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::reinterpret_cast_tag()); }
//!Trait class to detect if an smart pointer has
//!multi-segment addressing capabilities.
Modified: branches/release/boost/interprocess/detail/managed_memory_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_memory_impl.hpp (original)
+++ branches/release/boost/interprocess/detail/managed_memory_impl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -43,7 +43,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
template<class BasicManagedMemoryImpl>
class create_open_func;
@@ -583,7 +583,7 @@
//!For all theses reasons, classes with throwing destructors are not
//!recommended for memory.
template <class T>
- bool destroy(const detail::unique_instance_t *const )
+ bool destroy(const ipcdetail::unique_instance_t *const )
{ return mp_header->template destroy<T>(unique_instance); }
//!Destroys the object (named, unique, or anonymous)
@@ -724,13 +724,13 @@
class create_open_func
{
public:
- create_open_func(BasicManagedMemoryImpl * const frontend, detail::create_enum_t type)
+ create_open_func(BasicManagedMemoryImpl * const frontend, ipcdetail::create_enum_t type)
: m_frontend(frontend), m_type(type){}
bool operator()(void *addr, typename BasicManagedMemoryImpl::size_type size, bool created) const
{
- if(((m_type == detail::DoOpen) && created) ||
- ((m_type == detail::DoCreate) && !created))
+ if(((m_type == ipcdetail::DoOpen) && created) ||
+ ((m_type == ipcdetail::DoCreate) && !created))
return false;
if(created)
@@ -741,10 +741,10 @@
private:
BasicManagedMemoryImpl *m_frontend;
- detail::create_enum_t m_type;
+ ipcdetail::create_enum_t m_type;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -57,17 +57,17 @@
template<class IndexConfig> class IndexType
>
class basic_managed_multi_shared_memory
- : public detail::basic_managed_memory_impl
+ : public ipcdetail::basic_managed_memory_impl
<CharType, MemoryAlgorithm, IndexType>
{
typedef basic_managed_multi_shared_memory
<CharType, MemoryAlgorithm, IndexType> self_t;
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, MemoryAlgorithm, IndexType> base_t;
typedef typename MemoryAlgorithm::void_pointer void_pointer;
- typedef typename detail::
+ typedef typename ipcdetail::
managed_open_or_create_impl<shared_memory_object> managed_impl;
typedef typename void_pointer::segment_group_id segment_group_id;
typedef typename base_t::size_type size_type;
Modified: branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -32,7 +32,7 @@
namespace interprocess {
/// @cond
-namespace detail{ class interprocess_tester; }
+namespace ipcdetail{ class interprocess_tester; }
template<class DeviceAbstraction>
@@ -56,7 +56,7 @@
/// @endcond
-namespace detail {
+namespace ipcdetail {
template <bool StoreDevice, class DeviceAbstraction>
@@ -104,7 +104,7 @@
public:
static const std::size_t
ManagedOpenOrCreateUserOffset =
- detail::ct_rounded_size
+ ipcdetail::ct_rounded_size
< sizeof(boost::uint32_t)
, ::boost::alignment_of< ::boost::detail::max_align >::value >::value;
@@ -119,7 +119,7 @@
const permissions &perm)
{
priv_open_or_create
- ( detail::DoCreate
+ ( ipcdetail::DoCreate
, id
, size
, mode
@@ -134,7 +134,7 @@
const void *addr)
{
priv_open_or_create
- ( detail::DoOpen
+ ( ipcdetail::DoOpen
, id
, 0
, mode
@@ -152,7 +152,7 @@
const permissions &perm)
{
priv_open_or_create
- ( detail::DoOpenOrCreate
+ ( ipcdetail::DoOpenOrCreate
, id
, size
, mode
@@ -171,7 +171,7 @@
const permissions &perm)
{
priv_open_or_create
- (detail::DoCreate
+ (ipcdetail::DoCreate
, id
, size
, mode
@@ -188,7 +188,7 @@
const ConstructFunc &construct_func)
{
priv_open_or_create
- ( detail::DoOpen
+ ( ipcdetail::DoOpen
, id
, 0
, mode
@@ -207,7 +207,7 @@
const permissions &perm)
{
priv_open_or_create
- ( detail::DoOpenOrCreate
+ ( ipcdetail::DoOpenOrCreate
, id
, size
, mode
@@ -263,32 +263,32 @@
//These are templatized to allow explicit instantiations
template<bool dummy>
- static void truncate_device(DeviceAbstraction &, offset_t, detail::false_)
+ static void truncate_device(DeviceAbstraction &, offset_t, ipcdetail::false_)
{} //Empty
template<bool dummy>
- static void truncate_device(DeviceAbstraction &dev, offset_t size, detail::true_)
+ static void truncate_device(DeviceAbstraction &dev, offset_t size, ipcdetail::true_)
{ dev.truncate(size); }
template<bool dummy>
- static bool check_offset_t_size(std::size_t , detail::false_)
+ static bool check_offset_t_size(std::size_t , ipcdetail::false_)
{ return true; } //Empty
template<bool dummy>
- static bool check_offset_t_size(std::size_t size, detail::true_)
+ static bool check_offset_t_size(std::size_t size, ipcdetail::true_)
{ return size == std::size_t(offset_t(size)); }
//These are templatized to allow explicit instantiations
template<bool dummy>
- static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t size, const permissions &perm, detail::false_)
+ static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t size, const permissions &perm, ipcdetail::false_)
{
DeviceAbstraction tmp(create_only, id, read_write, size, perm);
tmp.swap(dev);
}
template<bool dummy>
- static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t, const permissions &perm, detail::true_)
+ static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t, const permissions &perm, ipcdetail::true_)
{
DeviceAbstraction tmp(create_only, id, read_write, perm);
tmp.swap(dev);
@@ -296,14 +296,14 @@
template <class ConstructFunc> inline
void priv_open_or_create
- (detail::create_enum_t type,
+ (ipcdetail::create_enum_t type,
const device_id_t & id,
std::size_t size,
mode_t mode, const void *addr,
const permissions &perm,
ConstructFunc construct_func)
{
- typedef detail::bool_<FileBased> file_like_t;
+ typedef ipcdetail::bool_<FileBased> file_like_t;
(void)mode;
error_info err;
bool created = false;
@@ -311,35 +311,35 @@
bool cow = false;
DeviceAbstraction dev;
- if(type != detail::DoOpen && size < ManagedOpenOrCreateUserOffset){
+ if(type != ipcdetail::DoOpen && size < ManagedOpenOrCreateUserOffset){
throw interprocess_exception(error_info(size_error));
}
//Check size can be represented by offset_t (used by truncate)
- if(type != detail::DoOpen && !check_offset_t_size<FileBased>(size, file_like_t())){
+ if(type != ipcdetail::DoOpen && !check_offset_t_size<FileBased>(size, file_like_t())){
throw interprocess_exception(error_info(size_error));
}
- if(type == detail::DoOpen && mode == read_write){
+ if(type == ipcdetail::DoOpen && mode == read_write){
DeviceAbstraction tmp(open_only, id, read_write);
tmp.swap(dev);
created = false;
}
- else if(type == detail::DoOpen && mode == read_only){
+ else if(type == ipcdetail::DoOpen && mode == read_only){
DeviceAbstraction tmp(open_only, id, read_only);
tmp.swap(dev);
created = false;
ronly = true;
}
- else if(type == detail::DoOpen && mode == copy_on_write){
+ else if(type == ipcdetail::DoOpen && mode == copy_on_write){
DeviceAbstraction tmp(open_only, id, read_only);
tmp.swap(dev);
created = false;
cow = true;
}
- else if(type == detail::DoCreate){
+ else if(type == ipcdetail::DoCreate){
create_device<FileBased>(dev, id, size, perm, file_like_t());
created = true;
}
- else if(type == detail::DoOpenOrCreate){
+ else if(type == ipcdetail::DoOpenOrCreate){
//This loop is very ugly, but brute force is sometimes better
//than diplomacy. If someone knows how to open or create a
//file and know if we have really created it or just open it
@@ -369,7 +369,7 @@
}
}
}
- detail::thread_yield();
+ ipcdetail::thread_yield();
}
}
@@ -382,7 +382,7 @@
mapped_region region(dev, read_write, 0, 0, addr);
boost::uint32_t *patomic_word = 0; //avoid gcc warning
patomic_word = static_cast<boost::uint32_t*>(region.get_address());
- boost::uint32_t previous = detail::atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment);
+ boost::uint32_t previous = ipcdetail::atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment);
if(previous == UninitializedSegment){
try{
@@ -391,10 +391,10 @@
m_mapped_region.swap(region);
}
catch(...){
- detail::atomic_write32(patomic_word, CorruptedSegment);
+ ipcdetail::atomic_write32(patomic_word, CorruptedSegment);
throw;
}
- detail::atomic_write32(patomic_word, InitializedSegment);
+ ipcdetail::atomic_write32(patomic_word, InitializedSegment);
}
else if(previous == InitializingSegment || previous == InitializedSegment){
throw interprocess_exception(error_info(already_exists_error));
@@ -416,10 +416,10 @@
if(FileBased){
offset_t filesize = 0;
while(filesize == 0){
- if(!detail::get_file_size(detail::file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){
+ if(!ipcdetail::get_file_size(ipcdetail::file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){
throw interprocess_exception(error_info(system_error_code()));
}
- detail::thread_yield();
+ ipcdetail::thread_yield();
}
if(filesize == 1){
throw interprocess_exception(error_info(corrupted_error));
@@ -429,11 +429,11 @@
mapped_region region(dev, ronly ? read_only : (cow ? copy_on_write : read_write), 0, 0, addr);
boost::uint32_t *patomic_word = static_cast<boost::uint32_t*>(region.get_address());
- boost::uint32_t value = detail::atomic_read32(patomic_word);
+ boost::uint32_t value = ipcdetail::atomic_read32(patomic_word);
while(value == InitializingSegment || value == UninitializedSegment){
- detail::thread_yield();
- value = detail::atomic_read32(patomic_word);
+ ipcdetail::thread_yield();
+ value = ipcdetail::atomic_read32(patomic_word);
}
if(value != InitializedSegment)
@@ -451,9 +451,9 @@
}
private:
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
- { detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
+ { ipcdetail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
mapped_region m_mapped_region;
};
@@ -463,7 +463,7 @@
,managed_open_or_create_impl<DeviceAbstraction> &y)
{ x.swap(y); }
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/math_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/math_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/math_functions.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -21,7 +21,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
// Greatest common divisor and least common multiple
@@ -103,7 +103,7 @@
return log2;
}
-} // namespace detail
+} // namespace ipcdetail
} // namespace interprocess
} // namespace boost
Modified: branches/release/boost/interprocess/detail/mpl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/mpl.hpp (original)
+++ branches/release/boost/interprocess/detail/mpl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -21,7 +21,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
template <class T, T val>
struct integral_constant
@@ -144,7 +144,7 @@
static const std::size_t value = 0;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/named_proxy.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/named_proxy.hpp (original)
+++ branches/release/boost/interprocess/detail/named_proxy.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -35,14 +35,14 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
template<class T, bool is_iterator, class ...Args>
struct CtorNArg : public placement_destroy<T>
{
- typedef detail::bool_<is_iterator> IsIterator;
+ typedef ipcdetail::bool_<is_iterator> IsIterator;
typedef CtorNArg<T, is_iterator, Args...> self_t;
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
@@ -71,15 +71,15 @@
private:
template<int ...IdxPack>
- void construct(void *mem, detail::true_, const index_tuple<IdxPack...>&)
+ void construct(void *mem, ipcdetail::true_, const index_tuple<IdxPack...>&)
{ new((void*)mem)T(*boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
template<int ...IdxPack>
- void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&)
+ void construct(void *mem, ipcdetail::false_, const index_tuple<IdxPack...>&)
{ new((void*)mem)T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
template<int ...IdxPack>
- void do_increment(detail::true_, const index_tuple<IdxPack...>&)
+ void do_increment(ipcdetail::true_, const index_tuple<IdxPack...>&)
{
this->expansion_helper(++get<IdxPack>(args_)...);
}
@@ -89,7 +89,7 @@
{}
template<int ...IdxPack>
- void do_increment(detail::false_, const index_tuple<IdxPack...>&)
+ void do_increment(ipcdetail::false_, const index_tuple<IdxPack...>&)
{}
tuple<Args&...> args_;
@@ -163,13 +163,13 @@
// struct Ctor2Arg
// : public placement_destroy<T>
// {
-// typedef detail::bool_<is_iterator> IsIterator;
+// typedef ipcdetail::bool_<is_iterator> IsIterator;
// typedef Ctor2Arg self_t;
//
-// void do_increment(detail::false_)
+// void do_increment(ipcdetail::false_)
// { ++m_p1; ++m_p2; }
//
-// void do_increment(detail::true_){}
+// void do_increment(ipcdetail::true_){}
//
// self_t& operator++()
// {
@@ -197,10 +197,10 @@
// }
//
// private:
-// void construct(void *mem, detail::true_)
+// void construct(void *mem, ipcdetail::true_)
// { new((void*)mem)T(*m_p1, *m_p2); }
//
-// void construct(void *mem, detail::false_)
+// void construct(void *mem, ipcdetail::false_)
// { new((void*)mem)T(m_p1, m_p2); }
//
// P1 &m_p1; P2 &m_p2;
@@ -218,13 +218,13 @@
struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
: public placement_destroy<T> \
{ \
- typedef detail::bool_<is_iterator> IsIterator; \
+ typedef ipcdetail::bool_<is_iterator> IsIterator; \
typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \
\
- void do_increment(detail::true_) \
+ void do_increment(ipcdetail::true_) \
{ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); } \
\
- void do_increment(detail::false_){} \
+ void do_increment(ipcdetail::false_){} \
\
self_t& operator++() \
{ \
@@ -250,13 +250,13 @@
} \
\
private: \
- void construct(void *mem, detail::true_) \
+ void construct(void *mem, ipcdetail::true_) \
{ \
new((void*)mem) T \
(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD, _)); \
} \
\
- void construct(void *mem, detail::false_) \
+ void construct(void *mem, ipcdetail::false_) \
{ \
new((void*)mem) T \
(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
@@ -342,7 +342,7 @@
#endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
-}}} //namespace boost { namespace interprocess { namespace detail {
+}}} //namespace boost { namespace interprocess { namespace ipcdetail {
#include <boost/interprocess/detail/config_end.hpp>
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -17,6 +17,7 @@
#include <boost/interprocess/permissions.hpp>
#include <string>
+#include <limits>
#if (defined BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
@@ -64,7 +65,7 @@
, file_current = winapi::file_current
} file_pos_t;
-namespace detail{
+namespace ipcdetail{
inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
{
@@ -127,6 +128,11 @@
if(!winapi::get_file_size(hnd, filesize))
return false;
+ if(size > (std::numeric_limits<offset_t>::max)()){
+ winapi::set_last_error(winapi::error_file_too_large);
+ return false;
+ }
+
if(size > (unsigned long long)filesize){
if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
return false;
@@ -365,7 +371,7 @@
, file_current = SEEK_CUR
} file_pos_t;
-namespace detail{
+namespace ipcdetail{
inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
{
@@ -438,7 +444,13 @@
{ return ::unlink(name) == 0; }
inline bool truncate_file (file_handle_t hnd, std::size_t size)
-{ return 0 == ::ftruncate(hnd, size); }
+{
+ if(off_t(size) < 0){
+ errno = EINVAL;
+ return false;
+ }
+ return 0 == ::ftruncate(hnd, size);
+}
inline bool get_file_size(file_handle_t hnd, offset_t &size)
{
@@ -669,7 +681,7 @@
}
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_thread_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/os_thread_functions.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -30,7 +30,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
#if (defined BOOST_INTERPROCESS_WINDOWS)
@@ -192,7 +192,7 @@
inline void get_pid_str(pid_str_t &pid_str)
{ get_pid_str(pid_str, get_current_process_id()); }
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess {
} //namespace boost {
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -24,7 +24,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
struct two {char _[2];};
@@ -61,10 +61,10 @@
struct pointer_type
{
typedef typename pointer_type_imp::pointer_type<T,
- typename detail::remove_reference<D>::type>::type type;
+ typename ipcdetail::remove_reference<D>::type>::type type;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/preprocessor.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/preprocessor.hpp (original)
+++ branches/release/boost/interprocess/detail/preprocessor.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -110,7 +110,7 @@
#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-#include <boost/interprocess/containers/container/detail/stored_ref.hpp>
+#include <boost/container/detail/stored_ref.hpp>
#define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
::boost::container::containers_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -28,7 +28,7 @@
namespace boost{
namespace interprocess{
-namespace detail{
+namespace ipcdetail{
namespace robust_emulation_helpers {
@@ -236,7 +236,7 @@
}
else{
//Do the dead owner checking each spin_threshold lock tries
- detail::thread_yield();
+ ipcdetail::thread_yield();
++spin_count;
if(spin_count > spin_threshold){
//Check if owner dead and take ownership if possible
@@ -302,7 +302,7 @@
return this->try_lock();
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}while (true);
return true;
@@ -425,12 +425,12 @@
{
//This function forces instantiation of the singleton
robust_emulation_helpers::robust_mutex_lock_file* dummy =
- &detail::intermodule_singleton
+ &ipcdetail::intermodule_singleton
<robust_emulation_helpers::robust_mutex_lock_file>::get();
return dummy != 0;
}
-} //namespace detail{
+} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
Modified: branches/release/boost/interprocess/detail/segment_manager_helper.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/segment_manager_helper.hpp (original)
+++ branches/release/boost/interprocess/detail/segment_manager_helper.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -51,7 +51,7 @@
//!instance constructed in memory
enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type };
-namespace detail{
+namespace ipcdetail{
template<class MemoryAlgorithm>
class mem_algo_deallocator
@@ -207,7 +207,7 @@
}
};
-inline void array_construct(void *mem, std::size_t num, detail::in_place_interface &table)
+inline void array_construct(void *mem, std::size_t num, ipcdetail::in_place_interface &table)
{
//Try constructors
std::size_t constructed = 0;
@@ -281,7 +281,7 @@
{
return const_cast<block_header<size_type>*>
(reinterpret_cast<const block_header<size_type> *>(reinterpret_cast<const char*>(this) +
- ::boost::interprocess::detail::get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment))));
+ ::boost::interprocess::ipcdetail::get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment))));
}
bool operator <(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
@@ -314,11 +314,11 @@
: m_name(name)
{}
- char_ptr_holder(const detail::anonymous_instance_t *)
+ char_ptr_holder(const ipcdetail::anonymous_instance_t *)
: m_name(static_cast<CharType*>(0))
{}
- char_ptr_holder(const detail::unique_instance_t *)
+ char_ptr_holder(const ipcdetail::unique_instance_t *)
: m_name(reinterpret_cast<CharType*>(-1))
{}
@@ -357,8 +357,8 @@
return (m_len < right.m_len) ||
(m_len == right.m_len &&
std::char_traits<char_type>::compare
- (detail::get_pointer(mp_str)
- ,detail::get_pointer(right.mp_str), m_len) < 0);
+ (ipcdetail::get_pointer(mp_str)
+ ,ipcdetail::get_pointer(right.mp_str), m_len) < 0);
}
//!Equal to function for index ordering
@@ -366,8 +366,8 @@
{
return m_len == right.m_len &&
std::char_traits<char_type>::compare
- (detail::get_pointer(mp_str),
- detail::get_pointer(right.mp_str), m_len) == 0;
+ (ipcdetail::get_pointer(mp_str),
+ ipcdetail::get_pointer(right.mp_str), m_len) == 0;
}
void name(const CharT *name)
@@ -377,7 +377,7 @@
{ m_len = len; }
const CharT *name() const
- { return detail::get_pointer(mp_str); }
+ { return ipcdetail::get_pointer(mp_str); }
size_type name_length() const
{ return m_len; }
@@ -393,7 +393,7 @@
index_data(void *ptr) : m_ptr(ptr){}
void *value() const
- { return static_cast<void*>(detail::get_pointer(m_ptr)); }
+ { return static_cast<void*>(ipcdetail::get_pointer(m_ptr)); }
};
template<class MemoryAlgorithm>
@@ -405,14 +405,14 @@
{
typedef typename MemoryAlgorithm::void_pointer void_pointer;
typedef CharT char_type;
- typedef detail::index_key<CharT, void_pointer> key_type;
- typedef detail::index_data<void_pointer> mapped_type;
+ typedef ipcdetail::index_key<CharT, void_pointer> key_type;
+ typedef ipcdetail::index_data<void_pointer> mapped_type;
typedef typename segment_manager_base_type
<MemoryAlgorithm>::type segment_manager_base;
template<class HeaderBase>
struct intrusive_value_type
- { typedef detail::intrusive_value_type_impl<HeaderBase, CharT, typename segment_manager_base::size_type> type; };
+ { typedef ipcdetail::intrusive_value_type_impl<HeaderBase, CharT, typename segment_manager_base::size_type> type; };
typedef intrusive_compare_key<CharT> intrusive_compare_key_type;
};
@@ -464,7 +464,7 @@
const void *value() const
{
return reinterpret_cast<block_header<size_type>*>
- (detail::get_pointer(m_val->second.m_ptr))->value();
+ (ipcdetail::get_pointer(m_val->second.m_ptr))->value();
}
const typename Iterator::value_type *m_val;
@@ -481,14 +481,14 @@
{ return result_type(arg); }
};
-} //namespace detail {
+} //namespace ipcdetail {
//These pointers are the ones the user will use to
//indicate previous allocation types
-static const detail::anonymous_instance_t * anonymous_instance = 0;
-static const detail::unique_instance_t * unique_instance = 0;
+static const ipcdetail::anonymous_instance_t * anonymous_instance = 0;
+static const ipcdetail::unique_instance_t * unique_instance = 0;
-namespace detail_really_deep_namespace {
+namespace ipcdetail_really_deep_namespace {
//Otherwise, gcc issues a warning of previously defined
//anonymous_instance and unique_instance
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -32,7 +32,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
#if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
inline void get_bootstamp(std::string &s, bool add = false)
@@ -166,7 +166,7 @@
} //namespace boost{
} //namespace interprocess {
-} //namespace detail {
+} //namespace ipcdetail {
#include <boost/interprocess/detail/config_end.hpp>
Modified: branches/release/boost/interprocess/detail/transform_iterator.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/transform_iterator.hpp (original)
+++ branches/release/boost/interprocess/detail/transform_iterator.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -62,7 +62,7 @@
: public UnaryFunction
, public std::iterator
< typename Iterator::iterator_category
- , typename detail::remove_reference<typename UnaryFunction::result_type>::type
+ , typename ipcdetail::remove_reference<typename UnaryFunction::result_type>::type
, typename Iterator::difference_type
, operator_arrow_proxy<typename UnaryFunction::result_type>
, typename UnaryFunction::result_type>
Modified: branches/release/boost/interprocess/detail/type_traits.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/type_traits.hpp (original)
+++ branches/release/boost/interprocess/detail/type_traits.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -21,7 +21,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
struct nat{};
@@ -112,7 +112,7 @@
static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
};
-} // namespace detail
+} // namespace ipcdetail
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/detail/utilities.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/utilities.hpp (original)
+++ branches/release/boost/interprocess/detail/utilities.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -35,7 +35,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
template<class SmartPtr>
struct smart_ptr_type
@@ -119,7 +119,7 @@
static const std::size_t value = 0;
};
-} //namespace detail {
+} //namespace ipcdetail {
//!Trait class to detect if an index is a node
//!index. This allows more efficient operations
Modified: branches/release/boost/interprocess/detail/variadic_templates_tools.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/variadic_templates_tools.hpp (original)
+++ branches/release/boost/interprocess/detail/variadic_templates_tools.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -22,7 +22,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
template<typename... Values>
class tuple;
@@ -146,7 +146,7 @@
{ typedef index_tuple<Indexes...> type; };
-}}} //namespace boost { namespace interprocess { namespace detail {
+}}} //namespace boost { namespace interprocess { namespace ipcdetail {
#include <boost/interprocess/detail/config_end.hpp>
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -51,6 +51,7 @@
//Retries in CreateFile, see http://support.microsoft.com/kb/316609
static const unsigned int error_sharing_violation_tries = 3u;
static const unsigned int error_sharing_violation_sleep_ms = 250u;
+static const unsigned int error_file_too_large = 223u;
static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3;
static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001;
@@ -789,7 +790,9 @@
, interprocess_filetime *lpExitTime,interprocess_filetime *lpKernelTime
, interprocess_filetime *lpUserTime );
extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long);
+extern "C" __declspec(dllimport) int __stdcall SwitchToThread();
extern "C" __declspec(dllimport) unsigned long __stdcall GetLastError();
+extern "C" __declspec(dllimport) void __stdcall SetLastError(unsigned long);
extern "C" __declspec(dllimport) void * __stdcall GetCurrentProcess();
extern "C" __declspec(dllimport) int __stdcall CloseHandle(void*);
extern "C" __declspec(dllimport) int __stdcall DuplicateHandle
@@ -899,6 +902,9 @@
inline unsigned long get_last_error()
{ return GetLastError(); }
+inline void set_last_error(unsigned long err)
+{ return SetLastError(err); }
+
inline unsigned long format_message
(unsigned long dwFlags, const void *lpSource,
unsigned long dwMessageId, unsigned long dwLanguageId,
@@ -916,7 +922,11 @@
{ return ((((unsigned short)(s)) << 10) | (unsigned short)(p)); }
inline void sched_yield()
-{ Sleep(1); }
+{
+ if(!SwitchToThread()){
+ Sleep(1);
+ }
+}
inline unsigned long get_current_thread_id()
{ return GetCurrentThreadId(); }
Modified: branches/release/boost/interprocess/detail/workaround.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/workaround.hpp (original)
+++ branches/release/boost/interprocess/detail/workaround.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -138,6 +138,11 @@
#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
+#endif
+
#include <boost/interprocess/detail/config_end.hpp>
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_WORKAROUND_HPP
Modified: branches/release/boost/interprocess/detail/xsi_shared_memory_device.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/xsi_shared_memory_device.hpp (original)
+++ branches/release/boost/interprocess/detail/xsi_shared_memory_device.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -53,22 +53,22 @@
xsi_shared_memory_device();
xsi_shared_memory_device(create_only_t, const char *name, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_only(detail::DoCreate, name, mode, size); }
+ { this->priv_open_or_create_name_only(ipcdetail::DoCreate, name, mode, size); }
xsi_shared_memory_device(open_or_create_t, const char *name, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_only(detail::DoOpenOrCreate, name, mode, size); }
+ { this->priv_open_or_create_name_only(ipcdetail::DoOpenOrCreate, name, mode, size); }
xsi_shared_memory_device(open_only_t, const char *name, mode_t mode)
- { this->priv_open_or_create_name_only(detail::DoOpen, name, mode, 0); }
+ { this->priv_open_or_create_name_only(ipcdetail::DoOpen, name, mode, 0); }
xsi_shared_memory_device(create_only_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_id(detail::DoCreate, name, id, mode, size); }
+ { this->priv_open_or_create_name_id(ipcdetail::DoCreate, name, id, mode, size); }
xsi_shared_memory_device(open_or_create_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
- { this->priv_open_or_create_name_id(detail::DoOpenOrCreate, id, name, mode, size); }
+ { this->priv_open_or_create_name_id(ipcdetail::DoOpenOrCreate, id, name, mode, size); }
xsi_shared_memory_device(open_only_t, const char *filepath, boost::uint8_t id, mode_t mode)
- { this->priv_open_or_create_name_id(detail::DoOpen, name, id, mode, 0); }
+ { this->priv_open_or_create_name_id(ipcdetail::DoOpen, name, id, mode, 0); }
xsi_shared_memory_device(BOOST_RV_REF(xsi_shared_memory_device) moved)
{ this->swap(moved); }
@@ -135,11 +135,11 @@
static void priv_obtain_index(mapped_region &m, xsi_named_mutex &m, std::string &path);
static bool priv_remove_dead_memory(info_t *info, const char *path);
- bool priv_open_or_create_name_only( detail::create_enum_t type
+ bool priv_open_or_create_name_only( ipcdetail::create_enum_t type
, const char *shmname
, mode_t mode
, std::size_t size);
- bool priv_open_or_create_name_id( detail::create_enum_t type
+ bool priv_open_or_create_name_id( ipcdetail::create_enum_t type
, const char *shmname
, boost::uint8_t id
, mode_t mode
@@ -197,8 +197,8 @@
permissions p;
p.set_unrestricted();
std::string xsi_shm_emulation_file_path;
- detail::create_tmp_and_clean_old_and_get_filename(filename, xsi_shm_emulation_file_path);
- detail::create_or_open_file(xsi_shm_emulation_file_path.c_str(), read_write, p);
+ ipcdetail::create_tmp_and_clean_old_and_get_filename(filename, xsi_shm_emulation_file_path);
+ ipcdetail::create_or_open_file(xsi_shm_emulation_file_path.c_str(), read_write, p);
const std::size_t MemSize = sizeof(info_t);
xsi_shared_memory index_shm(open_or_create, xsi_shm_emulation_file_path.c_str(), 1, MemSize, 0666);
@@ -230,7 +230,7 @@
}
inline bool xsi_shared_memory_device::priv_open_or_create_name_id
- (detail::create_enum_t type, const char *filepath, mode_t mode, std::size_t size)
+ (ipcdetail::create_enum_t type, const char *filepath, mode_t mode, std::size_t size)
{
//Set accesses
if (mode != read_write && mode != read_only){
@@ -240,7 +240,7 @@
int perm = (mode == read_only) ? (0444) : (0666);
- if(type == detail::DoOpen){
+ if(type == ipcdetail::DoOpen){
if(!found){
error_info err = not_found_error;
throw interprocess_exception(err);
@@ -248,13 +248,13 @@
xsi_shared_memory temp(open_only, filepath, id, perm);
m_shm = boost::interprocess::move(temp);
}
- else if(type == detail::DoCreate){
+ else if(type == ipcdetail::DoCreate){
//Try to reuse slot
xsi_shared_memory temp(create_only, filepath, id, size, perm);
std::strcpy(info->names[target_entry].buf, shmname);
m_shm = boost::interprocess::move(temp);
}
- else{ // if(type == detail::DoOpenOrCreate){
+ else{ // if(type == ipcdetail::DoOpenOrCreate){
xsi_shared_memory temp(open_or_create, filepath, id, size, perm);
m_shm = boost::interprocess::move(temp);
}
@@ -265,7 +265,7 @@
}
inline bool xsi_shared_memory_device::priv_open_or_create_name_only
- (detail::create_enum_t type, const char *shmname, mode_t mode, std::size_t size)
+ (ipcdetail::create_enum_t type, const char *shmname, mode_t mode, std::size_t size)
{
//Set accesses
if (mode != read_write && mode != read_only){
@@ -311,7 +311,7 @@
}
//Now handle the result
int perm = (mode == read_only) ? (0444) : (0666);
- if(type == detail::DoOpen){
+ if(type == ipcdetail::DoOpen){
if(!found){
error_info err = not_found_error;
throw interprocess_exception(err);
@@ -322,14 +322,14 @@
}
else{
- if(type == detail::DoCreate){
+ if(type == ipcdetail::DoCreate){
//Try to reuse slot
xsi_shared_memory temp( create_only, xsi_shm_emulation_file_path.c_str()
, target_entry+info_constants_t<0>::FirstID, size, perm);
std::strcpy(info->names[target_entry].buf, shmname);
m_shm = boost::interprocess::move(temp);
}
- else{ // if(type == detail::DoOpenOrCreate){
+ else{ // if(type == ipcdetail::DoOpenOrCreate){
xsi_shared_memory temp( open_or_create, xsi_shm_emulation_file_path.c_str()
, target_entry+info_constants_t<0>::FirstID, size, perm);
if(!found){
Modified: branches/release/boost/interprocess/errors.hpp
==============================================================================
--- branches/release/boost/interprocess/errors.hpp (original)
+++ branches/release/boost/interprocess/errors.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -112,7 +112,8 @@
size_error,
corrupted_error,
not_such_file_or_directory,
- invalid_argument
+ invalid_argument,
+ timeout_when_locking_error,
};
typedef int native_error_t;
Modified: branches/release/boost/interprocess/file_mapping.hpp
==============================================================================
--- branches/release/boost/interprocess/file_mapping.hpp (original)
+++ branches/release/boost/interprocess/file_mapping.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -51,7 +51,7 @@
//!After the call, "moved" does not represent any file mapping object.
//!Does not throw
file_mapping(BOOST_RV_REF(file_mapping) moved)
- : m_handle(file_handle_t(detail::invalid_file()))
+ : m_handle(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s file mapping to *this.
@@ -101,7 +101,7 @@
};
inline file_mapping::file_mapping()
- : m_handle(file_handle_t(detail::invalid_file()))
+ : m_handle(file_handle_t(ipcdetail::invalid_file()))
{}
inline file_mapping::~file_mapping()
@@ -118,7 +118,7 @@
}
inline mapping_handle_t file_mapping::get_mapping_handle() const
-{ return detail::mapping_handle_from_file_handle(m_handle); }
+{ return ipcdetail::mapping_handle_from_file_handle(m_handle); }
inline mode_t file_mapping::get_mode() const
{ return m_mode; }
@@ -134,10 +134,10 @@
}
//Open file
- m_handle = detail::open_existing_file(filename, mode);
+ m_handle = ipcdetail::open_existing_file(filename, mode);
//Check for error
- if(m_handle == detail::invalid_file()){
+ if(m_handle == ipcdetail::invalid_file()){
error_info err = system_error_code();
this->priv_close();
throw interprocess_exception(err);
@@ -146,15 +146,15 @@
}
inline bool file_mapping::remove(const char *filename)
-{ return detail::delete_file(filename); }
+{ return ipcdetail::delete_file(filename); }
///@cond
inline void file_mapping::priv_close()
{
- if(m_handle != detail::invalid_file()){
- detail::close_file(m_handle);
- m_handle = detail::invalid_file();
+ if(m_handle != ipcdetail::invalid_file()){
+ ipcdetail::close_file(m_handle);
+ m_handle = ipcdetail::invalid_file();
}
}
@@ -173,7 +173,7 @@
{}
~remove_file_on_destroy()
- { detail::delete_file(m_name); }
+ { ipcdetail::delete_file(m_name); }
};
} //namespace interprocess {
Modified: branches/release/boost/interprocess/indexes/iunordered_set_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/iunordered_set_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/iunordered_set_index.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -84,7 +84,7 @@
{
std::size_t operator()(const value_type &val) const
{
- const char_type *beg = detail::get_pointer(val.name()),
+ const char_type *beg = ipcdetail::get_pointer(val.name()),
*end = beg + val.name_length();
return boost::hash_range(beg, end);
}
@@ -181,8 +181,8 @@
return old_size;
}
- for( bucket_type *p = detail::get_pointer(buckets) + received_size
- , *pend = detail::get_pointer(buckets) + old_size
+ for( bucket_type *p = ipcdetail::get_pointer(buckets) + received_size
+ , *pend = ipcdetail::get_pointer(buckets) + old_size
; p != pend
; ++p){
p->~bucket_type();
Modified: branches/release/boost/interprocess/indexes/map_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/map_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/map_index.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -25,7 +25,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
//!Helper class to define typedefs from IndexTraits
template <class MapConfig>
@@ -46,17 +46,17 @@
key_less, allocator_type> index_t;
};
-} //namespace detail {
+} //namespace ipcdetail {
//!Index type based in boost::interprocess::map. Just derives from boost::interprocess::map
//!and defines the interface needed by managed memory segments
template <class MapConfig>
class map_index
//Derive class from map specialization
- : public detail::map_index_aux<MapConfig>::index_t
+ : public ipcdetail::map_index_aux<MapConfig>::index_t
{
/// @cond
- typedef detail::map_index_aux<MapConfig> index_aux;
+ typedef ipcdetail::map_index_aux<MapConfig> index_aux;
typedef typename index_aux::index_t base_type;
typedef typename MapConfig::
segment_manager_base segment_manager_base;
Modified: branches/release/boost/interprocess/indexes/unordered_map_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/unordered_map_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/unordered_map_index.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -48,7 +48,7 @@
std::size_t operator()(const key_type &val) const
{
typedef typename key_type::char_type char_type;
- const char_type *beg = detail::get_pointer(val.mp_str),
+ const char_type *beg = ipcdetail::get_pointer(val.mp_str),
*end = beg + val.m_len;
return boost::hash_range(beg, end);
}
Modified: branches/release/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- branches/release/boost/interprocess/ipc/message_queue.hpp (original)
+++ branches/release/boost/interprocess/ipc/message_queue.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -173,13 +173,13 @@
//!Never throws
static size_type get_mem_size(size_type max_msg_size, size_type max_num_msg);
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
/// @endcond
};
/// @cond
-namespace detail {
+namespace ipcdetail {
//!This header is the prefix of each message in the queue
template<class VoidPointer>
@@ -245,7 +245,7 @@
//! the index structure.
template<class VoidPointer>
class mq_hdr_t
- : public detail::priority_functor<VoidPointer>
+ : public ipcdetail::priority_functor<VoidPointer>
{
typedef VoidPointer void_pointer;
typedef msg_hdr_t<void_pointer> msg_header;
@@ -312,11 +312,11 @@
const size_type
msg_hdr_align = ::boost::alignment_of<msg_header>::value,
index_align = ::boost::alignment_of<msg_hdr_ptr_t>::value,
- r_hdr_size = detail::ct_rounded_size<sizeof(mq_hdr_t), index_align>::value,
- r_index_size = detail::get_rounded_size(sizeof(msg_hdr_ptr_t)*max_num_msg, msg_hdr_align),
- r_max_msg_size = detail::get_rounded_size(max_msg_size, msg_hdr_align) + sizeof(msg_header);
+ r_hdr_size = ipcdetail::ct_rounded_size<sizeof(mq_hdr_t), index_align>::value,
+ r_index_size = ipcdetail::get_rounded_size(sizeof(msg_hdr_ptr_t)*max_num_msg, msg_hdr_align),
+ r_max_msg_size = ipcdetail::get_rounded_size(max_msg_size, msg_hdr_align) + sizeof(msg_header);
return r_hdr_size + r_index_size + (max_num_msg*r_max_msg_size) +
- detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset;
}
//!Initializes the memory structures to preallocate messages and constructs the
@@ -326,9 +326,9 @@
const size_type
msg_hdr_align = ::boost::alignment_of<msg_header>::value,
index_align = ::boost::alignment_of<msg_hdr_ptr_t>::value,
- r_hdr_size = detail::ct_rounded_size<sizeof(mq_hdr_t), index_align>::value,
- r_index_size = detail::get_rounded_size(sizeof(msg_hdr_ptr_t)*m_max_num_msg, msg_hdr_align),
- r_max_msg_size = detail::get_rounded_size(m_max_msg_size, msg_hdr_align) + sizeof(msg_header);
+ r_hdr_size = ipcdetail::ct_rounded_size<sizeof(mq_hdr_t), index_align>::value,
+ r_index_size = ipcdetail::get_rounded_size(sizeof(msg_hdr_ptr_t)*m_max_num_msg, msg_hdr_align),
+ r_max_msg_size = ipcdetail::get_rounded_size(m_max_msg_size, msg_hdr_align) + sizeof(msg_header);
//Pointer to the index
msg_hdr_ptr_t *index = reinterpret_cast<msg_hdr_ptr_t*>
@@ -402,7 +402,7 @@
const size_type m_maxmsgsize;
};
-} //namespace detail {
+} //namespace ipcdetail {
template<class VoidPointer>
inline message_queue_t<VoidPointer>::~message_queue_t()
@@ -411,7 +411,7 @@
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_mem_size
(size_type max_msg_size, size_type max_num_msg)
-{ return detail::mq_hdr_t<VoidPointer>::get_mem_size(max_msg_size, max_num_msg); }
+{ return ipcdetail::mq_hdr_t<VoidPointer>::get_mem_size(max_msg_size, max_num_msg); }
template<class VoidPointer>
inline message_queue_t<VoidPointer>::message_queue_t(create_only_t create_only,
@@ -426,7 +426,7 @@
read_write,
static_cast<void*>(0),
//Prepare initialization functor
- detail::initialization_func_t<VoidPointer> (max_num_msg, max_msg_size),
+ ipcdetail::initialization_func_t<VoidPointer> (max_num_msg, max_msg_size),
perm)
{}
@@ -443,7 +443,7 @@
read_write,
static_cast<void*>(0),
//Prepare initialization functor
- detail::initialization_func_t<VoidPointer> (max_num_msg, max_msg_size),
+ ipcdetail::initialization_func_t<VoidPointer> (max_num_msg, max_msg_size),
perm)
{}
@@ -456,7 +456,7 @@
read_write,
static_cast<void*>(0),
//Prepare initialization functor
- detail::initialization_func_t<VoidPointer> ())
+ ipcdetail::initialization_func_t<VoidPointer> ())
{}
template<class VoidPointer>
@@ -486,7 +486,7 @@
const void *buffer, size_type buffer_size,
unsigned int priority, const boost::posix_time::ptime &abs_time)
{
- detail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<detail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
+ ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
//Check if buffer is smaller than maximum allowed
if (buffer_size > p_hdr->m_max_msg_size) {
throw interprocess_exception(size_error);
@@ -527,7 +527,7 @@
}
//Get the first free message from free message queue
- detail::msg_hdr_t<VoidPointer> *free_msg = p_hdr->free_msg();
+ ipcdetail::msg_hdr_t<VoidPointer> *free_msg = p_hdr->free_msg();
if (free_msg == 0) {
throw interprocess_exception("boost::interprocess::message_queue corrupted");
}
@@ -583,7 +583,7 @@
size_type &recvd_size, unsigned int &priority,
const boost::posix_time::ptime &abs_time)
{
- detail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<detail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
+ ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
//Check if buffer is big enough for any message
if (buffer_size < p_hdr->m_max_msg_size) {
throw interprocess_exception(size_error);
@@ -625,7 +625,7 @@
}
//Thre is at least message ready to pick, get the top one
- detail::msg_hdr_t<VoidPointer> *top_msg = p_hdr->top_msg();
+ ipcdetail::msg_hdr_t<VoidPointer> *top_msg = p_hdr->top_msg();
//Paranoia check
if (top_msg == 0) {
@@ -656,20 +656,20 @@
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_max_msg() const
{
- detail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<detail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
+ ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
return p_hdr ? p_hdr->m_max_num_msg : 0; }
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_max_msg_size() const
{
- detail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<detail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
+ ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
return p_hdr ? p_hdr->m_max_msg_size : 0;
}
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_num_msg()
{
- detail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<detail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
+ ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
if(p_hdr){
//---------------------------------------------
scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);
Modified: branches/release/boost/interprocess/managed_external_buffer.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_external_buffer.hpp (original)
+++ branches/release/boost/interprocess/managed_external_buffer.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -38,10 +38,10 @@
template<class IndexConfig> class IndexType
>
class basic_managed_external_buffer
- : public detail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
+ : public ipcdetail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
{
/// @cond
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType> base_t;
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_external_buffer)
/// @endcond
Modified: branches/release/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_heap_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_heap_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -39,12 +39,12 @@
template<class IndexConfig> class IndexType
>
class basic_managed_heap_memory
- : public detail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
+ : public ipcdetail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
{
/// @cond
private:
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType> base_t;
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_heap_memory)
/// @endcond
Modified: branches/release/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_mapped_file.hpp (original)
+++ branches/release/boost/interprocess/managed_mapped_file.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -38,22 +38,22 @@
template<class IndexConfig> class IndexType
>
class basic_managed_mapped_file
- : public detail::basic_managed_memory_impl
+ : public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
- ,detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset>
+ ,ipcdetail::managed_open_or_create_impl<ipcdetail::file_wrapper>::ManagedOpenOrCreateUserOffset>
{
/// @cond
public:
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
- detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset> base_t;
- typedef detail::file_wrapper device_type;
+ ipcdetail::managed_open_or_create_impl<ipcdetail::file_wrapper>::ManagedOpenOrCreateUserOffset> base_t;
+ typedef ipcdetail::file_wrapper device_type;
typedef typename base_t::size_type size_type;
private:
- typedef detail::create_open_func<base_t> create_open_func_t;
- typedef detail::managed_open_or_create_impl<detail::file_wrapper> managed_open_or_create_type;
+ typedef ipcdetail::create_open_func<base_t> create_open_func_t;
+ typedef ipcdetail::managed_open_or_create_impl<ipcdetail::file_wrapper> managed_open_or_create_type;
basic_managed_mapped_file *get_this_pointer()
{ return this; }
@@ -75,7 +75,7 @@
basic_managed_mapped_file(create_only_t create_only, const char *name,
size_type size, const void *addr = 0, const permissions &perm = permissions())
: m_mfile(create_only, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(), detail::DoCreate), perm)
+ create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
//!Creates mapped file and creates and places the segment manager if
@@ -87,7 +87,7 @@
const void *addr = 0, const permissions &perm = permissions())
: m_mfile(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpenOrCreate), perm)
+ ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created mapped file and its segment manager.
@@ -96,7 +96,7 @@
const void *addr = 0)
: m_mfile(open_only, name, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Connects to a created mapped file and its segment manager
@@ -106,7 +106,7 @@
const void *addr = 0)
: m_mfile(open_only, name, copy_on_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Connects to a created mapped file and its segment manager
@@ -116,7 +116,7 @@
const void *addr = 0)
: m_mfile(open_only, name, read_only, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Moves the ownership of "moved"'s managed memory to *this.
Modified: branches/release/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -39,19 +39,19 @@
template<class IndexConfig> class IndexType
>
class basic_managed_shared_memory
- : public detail::basic_managed_memory_impl
+ : public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
- ,detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset>
- , private detail::managed_open_or_create_impl<shared_memory_object>
+ ,ipcdetail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset>
+ , private ipcdetail::managed_open_or_create_impl<shared_memory_object>
{
/// @cond
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
- detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset> base_t;
- typedef detail::managed_open_or_create_impl
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset> base_t;
+ typedef ipcdetail::managed_open_or_create_impl
<shared_memory_object> base2_t;
- typedef detail::create_open_func<base_t> create_open_func_t;
+ typedef ipcdetail::create_open_func<base_t> create_open_func_t;
basic_managed_shared_memory *get_this_pointer()
{ return this; }
@@ -87,7 +87,7 @@
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(), detail::DoCreate), perm)
+ create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
//!Creates shared memory and creates and places the segment manager if
@@ -100,7 +100,7 @@
: base_t()
, base2_t(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpenOrCreate), perm)
+ ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created shared memory and its segment manager.
@@ -111,7 +111,7 @@
: base_t()
, base2_t(open_only, name, copy_on_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager.
@@ -122,7 +122,7 @@
: base_t()
, base2_t(open_only, name, read_only, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager.
@@ -132,7 +132,7 @@
: base_t()
, base2_t(open_only, name, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Moves the ownership of "moved"'s managed memory to *this.
Modified: branches/release/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_windows_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -45,16 +45,16 @@
template<class IndexConfig> class IndexType
>
class basic_managed_windows_shared_memory
- : public detail::basic_managed_memory_impl
+ : public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
- ,detail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset>
+ ,ipcdetail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset>
{
/// @cond
private:
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
- detail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset> base_t;
- typedef detail::create_open_func<base_t> create_open_func_t;
+ ipcdetail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset> base_t;
+ typedef ipcdetail::create_open_func<base_t> create_open_func_t;
basic_managed_windows_shared_memory *get_this_pointer()
{ return this; }
@@ -78,7 +78,7 @@
(create_only_t create_only, const char *name,
size_type size, const void *addr = 0, const permissions &perm = permissions())
: m_wshm(create_only, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(), detail::DoCreate), perm)
+ create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
//!Creates shared memory and creates and places the segment manager if
@@ -92,7 +92,7 @@
const permissions &perm = permissions())
: m_wshm(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpenOrCreate), perm)
+ ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created shared memory and its segment manager.
@@ -101,7 +101,7 @@
(open_only_t open_only, const char* name, const void *addr = 0)
: m_wshm(open_only, name, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager
@@ -110,7 +110,7 @@
basic_managed_windows_shared_memory
(open_copy_on_write_t, const char* name, const void *addr = 0)
: m_wshm(open_only, name, copy_on_write, addr,
- create_open_func_t(get_this_pointer(), detail::DoOpen))
+ create_open_func_t(get_this_pointer(), ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager
@@ -120,7 +120,7 @@
(open_read_only_t, const char* name, const void *addr = 0)
: base_t()
, m_wshm(open_only, name, read_only, addr,
- create_open_func_t(get_this_pointer(), detail::DoOpen))
+ create_open_func_t(get_this_pointer(), ipcdetail::DoOpen))
{}
//!Moves the ownership of "moved"'s managed memory to *this.
@@ -171,7 +171,7 @@
}
private:
- detail::managed_open_or_create_impl<windows_shared_memory, false> m_wshm;
+ ipcdetail::managed_open_or_create_impl<windows_shared_memory, false> m_wshm;
/// @endcond
};
Modified: branches/release/boost/interprocess/managed_xsi_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_xsi_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_xsi_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -41,23 +41,23 @@
template<class IndexConfig> class IndexType
>
class basic_managed_xsi_shared_memory
- : public detail::basic_managed_memory_impl
+ : public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
- ,detail::managed_open_or_create_impl<xsi_shared_memory_file_wrapper, false, true>::ManagedOpenOrCreateUserOffset>
- , private detail::managed_open_or_create_impl<xsi_shared_memory_file_wrapper, false, true>
+ ,ipcdetail::managed_open_or_create_impl<xsi_shared_memory_file_wrapper, false, true>::ManagedOpenOrCreateUserOffset>
+ , private ipcdetail::managed_open_or_create_impl<xsi_shared_memory_file_wrapper, false, true>
{
/// @cond
public:
typedef xsi_shared_memory_file_wrapper device_type;
public:
- typedef detail::managed_open_or_create_impl
+ typedef ipcdetail::managed_open_or_create_impl
<xsi_shared_memory_file_wrapper, false, true> base2_t;
- typedef detail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
base2_t::ManagedOpenOrCreateUserOffset> base_t;
- typedef detail::create_open_func<base_t> create_open_func_t;
+ typedef ipcdetail::create_open_func<base_t> create_open_func_t;
basic_managed_xsi_shared_memory *get_this_pointer()
{ return this; }
@@ -90,7 +90,7 @@
std::size_t size, const void *addr = 0, const permissions& perm = permissions())
: base_t()
, base2_t(create_only, key, size, read_write, addr,
- create_open_func_t(get_this_pointer(), detail::DoCreate), perm)
+ create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
//!Creates shared memory and creates and places the segment manager if
@@ -103,7 +103,7 @@
: base_t()
, base2_t(open_or_create, key, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpenOrCreate), perm)
+ ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created shared memory and its segment manager.
@@ -114,7 +114,7 @@
: base_t()
, base2_t(open_only, key, read_only, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager.
@@ -124,7 +124,7 @@
: base_t()
, base2_t(open_only, key, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoOpen))
+ ipcdetail::DoOpen))
{}
//!Moves the ownership of "moved"'s managed memory to *this.
Modified: branches/release/boost/interprocess/mapped_region.hpp
==============================================================================
--- branches/release/boost/interprocess/mapped_region.hpp (original)
+++ branches/release/boost/interprocess/mapped_region.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -48,8 +48,8 @@
namespace interprocess {
/// @cond
-namespace detail{ class interprocess_tester; }
-namespace detail{ class raw_mapped_region_creator; }
+namespace ipcdetail{ class interprocess_tester; }
+namespace ipcdetail{ class raw_mapped_region_creator; }
/// @endcond
@@ -86,7 +86,7 @@
: m_base(0), m_size(0), m_offset(0)
, m_extra_offset(0)
, m_mode(read_only)
- , m_file_mapping_hnd(detail::invalid_file())
+ , m_file_mapping_hnd(ipcdetail::invalid_file())
#else
: m_base(MAP_FAILED), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only), m_is_xsi(false)
#endif
@@ -158,8 +158,8 @@
bool m_is_xsi;
#endif
- friend class detail::interprocess_tester;
- friend class detail::raw_mapped_region_creator;
+ friend class ipcdetail::interprocess_tester;
+ friend class ipcdetail::raw_mapped_region_creator;
void dont_close_on_destruction();
/// @endcond
};
@@ -188,7 +188,7 @@
inline mapped_region::mapped_region()
: m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only)
- , m_file_mapping_hnd(detail::invalid_file())
+ , m_file_mapping_hnd(ipcdetail::invalid_file())
{}
template<int dummy>
@@ -207,7 +207,7 @@
,std::size_t size
,const void *address)
: m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(mode)
- , m_file_mapping_hnd(detail::invalid_file())
+ , m_file_mapping_hnd(ipcdetail::invalid_file())
{
mapping_handle_t mhandle = mapping.get_mapping_handle();
file_handle_t native_mapping_handle = 0;
@@ -244,7 +244,7 @@
if(size == 0){
__int64 total_size;
if(!winapi::get_file_size
- (detail::file_handle_from_mapping_handle
+ (ipcdetail::file_handle_from_mapping_handle
(mapping.get_mapping_handle()), total_size)){
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
@@ -261,7 +261,7 @@
//Create file mapping
native_mapping_handle =
winapi::create_file_mapping
- (detail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), file_map_access, 0, 0, 0, 0);
+ (ipcdetail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), file_map_access, 0, 0, 0, 0);
//Check if all is correct
if(!native_mapping_handle){
@@ -364,9 +364,9 @@
m_base = 0;
}
#if (defined BOOST_INTERPROCESS_WINDOWS)
- if(m_file_mapping_hnd != detail::invalid_file()){
+ if(m_file_mapping_hnd != ipcdetail::invalid_file()){
winapi::close_handle(m_file_mapping_hnd);
- m_file_mapping_hnd = detail::invalid_file();
+ m_file_mapping_hnd = ipcdetail::invalid_file();
}
#endif
}
@@ -579,15 +579,15 @@
inline void mapped_region::swap(mapped_region &other)
{
- detail::do_swap(this->m_base, other.m_base);
- detail::do_swap(this->m_size, other.m_size);
- detail::do_swap(this->m_offset, other.m_offset);
- detail::do_swap(this->m_extra_offset, other.m_extra_offset);
- detail::do_swap(this->m_mode, other.m_mode);
+ ipcdetail::do_swap(this->m_base, other.m_base);
+ ipcdetail::do_swap(this->m_size, other.m_size);
+ ipcdetail::do_swap(this->m_offset, other.m_offset);
+ ipcdetail::do_swap(this->m_extra_offset, other.m_extra_offset);
+ ipcdetail::do_swap(this->m_mode, other.m_mode);
#if (defined BOOST_INTERPROCESS_WINDOWS)
- detail::do_swap(this->m_file_mapping_hnd, other.m_file_mapping_hnd);
+ ipcdetail::do_swap(this->m_file_mapping_hnd, other.m_file_mapping_hnd);
#else
- detail::do_swap(this->m_is_xsi, other.m_is_xsi);
+ ipcdetail::do_swap(this->m_is_xsi, other.m_is_xsi);
#endif
}
Modified: branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -38,7 +38,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
//!This class implements several allocation functions shared by different algorithms
//!(aligned allocation, multiple allocation...).
@@ -73,13 +73,13 @@
{ return (((std::size_t)ptr) % Alignment == 0); }
static size_type ceil_units(size_type size)
- { return detail::get_rounded_size(size, Alignment)/Alignment; }
+ { return ipcdetail::get_rounded_size(size, Alignment)/Alignment; }
static size_type floor_units(size_type size)
{ return size/Alignment; }
static size_type multiple_of_units(size_type size)
- { return detail::get_rounded_size(size, Alignment); }
+ { return ipcdetail::get_rounded_size(size, Alignment); }
static multiallocation_chain allocate_many
(MemoryAlgorithm *memory_algo, size_type elem_bytes, size_type n_elements)
@@ -119,10 +119,10 @@
//If we want to use minbytes data to get a buffer between maxbytes
//and minbytes if maxbytes can't be achieved, calculate the
//biggest of all possibilities
- current_forward = detail::get_truncated_size_po2(received_size, backwards_multiple);
+ current_forward = ipcdetail::get_truncated_size_po2(received_size, backwards_multiple);
needs_backwards = size_to_achieve - current_forward;
BOOST_ASSERT((needs_backwards % backwards_multiple) == 0);
- needs_backwards_lcmed = detail::get_rounded_size_po2(needs_backwards, lcm);
+ needs_backwards_lcmed = ipcdetail::get_rounded_size_po2(needs_backwards, lcm);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
@@ -130,7 +130,7 @@
//Check if it's multiple of alignment
else if((backwards_multiple & (Alignment - 1u)) == 0){
lcm = backwards_multiple;
- current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ current_forward = ipcdetail::get_truncated_size(received_size, backwards_multiple);
//No need to round needs_backwards because backwards_multiple == lcm
needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
BOOST_ASSERT((needs_backwards_lcmed & (Alignment - 1u)) == 0);
@@ -141,7 +141,7 @@
//Check if it's multiple of the half of the alignmment
else if((backwards_multiple & ((Alignment/2u) - 1u)) == 0){
lcm = backwards_multiple*2u;
- current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ current_forward = ipcdetail::get_truncated_size(received_size, backwards_multiple);
needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
if(0 != (needs_backwards_lcmed & (Alignment-1)))
//while(0 != (needs_backwards_lcmed & (Alignment-1)))
@@ -155,7 +155,7 @@
else if((backwards_multiple & ((Alignment/4u) - 1u)) == 0){
size_type remainder;
lcm = backwards_multiple*4u;
- current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ current_forward = ipcdetail::get_truncated_size(received_size, backwards_multiple);
needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
//while(0 != (needs_backwards_lcmed & (Alignment-1)))
//needs_backwards_lcmed += backwards_multiple;
@@ -173,15 +173,15 @@
return true;
}
else{
- lcm = detail::lcm(max, min);
+ lcm = ipcdetail::lcm(max, min);
}
//If we want to use minbytes data to get a buffer between maxbytes
//and minbytes if maxbytes can't be achieved, calculate the
//biggest of all possibilities
- current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ current_forward = ipcdetail::get_truncated_size(received_size, backwards_multiple);
needs_backwards = size_to_achieve - current_forward;
BOOST_ASSERT((needs_backwards % backwards_multiple) == 0);
- needs_backwards_lcmed = detail::get_rounded_size(needs_backwards, lcm);
+ needs_backwards_lcmed = ipcdetail::get_rounded_size(needs_backwards, lcm);
lcm_out = lcm;
needs_backwards_lcmed_out = needs_backwards_lcmed;
return true;
@@ -538,14 +538,14 @@
static void priv_deallocate_many(MemoryAlgorithm *memory_algo, multiallocation_chain chain)
{
while(!chain.empty()){
- void *addr = detail::get_pointer(chain.front());
+ void *addr = ipcdetail::get_pointer(chain.front());
chain.pop_front();
memory_algo->priv_deallocate(addr);
}
}
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -34,9 +34,9 @@
linked list of free buffers.*/
template<class MutexFamily, class VoidPtr>
class multi_simple_seq_fit
- : public detail::simple_seq_fit_impl<MutexFamily, VoidPtr>
+ : public ipcdetail::simple_seq_fit_impl<MutexFamily, VoidPtr>
{
- typedef detail::simple_seq_fit_impl<MutexFamily, VoidPtr> base_t;
+ typedef ipcdetail::simple_seq_fit_impl<MutexFamily, VoidPtr> base_t;
public:
/*!Constructor. "size" is the total size of the managed memory segment,
"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(multi_simple_seq_fit)
Modified: branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -48,7 +48,7 @@
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
/*!This class implements the simple sequential fit algorithm with a simply
linked list of free buffers.
@@ -222,8 +222,8 @@
/*!Makes a new memory portion available for allocation*/
void priv_add_segment(void *addr, size_type size);
- enum { Alignment = ::boost::alignment_of<boost::detail::max_align>::value };
- enum { BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value };
+ enum { Alignment = ::boost::alignment_of<boost::ipcdetail::max_align>::value };
+ enum { BlockCtrlBytes = ipcdetail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value };
enum { BlockCtrlSize = BlockCtrlBytes/Alignment };
enum { MinBlockSize = BlockCtrlSize + Alignment };
@@ -240,7 +240,7 @@
m_header.m_size = size;
//Initialize pointers
- size_type block1_off = detail::get_rounded_size(sizeof(*this)+extra_hdr_bytes, Alignment);
+ size_type block1_off = ipcdetail::get_rounded_size(sizeof(*this)+extra_hdr_bytes, Alignment);
m_header.m_root.m_next = reinterpret_cast<block_ctrl*>
(reinterpret_cast<char*>(this) + block1_off);
m_header.m_root.m_next->m_size = (size - block1_off)/Alignment;
@@ -306,7 +306,7 @@
simple_seq_fit_impl<MutexFamily, VoidPointer>::
get_min_size (size_type extra_hdr_bytes)
{
- return detail::get_rounded_size(sizeof(simple_seq_fit_impl)+extra_hdr_bytes
+ return ipcdetail::get_rounded_size(sizeof(simple_seq_fit_impl)+extra_hdr_bytes
,Alignment)
+ MinBlockSize;
}
@@ -319,7 +319,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
return m_header.m_allocated == 0 &&
- detail::get_pointer(m_header.m_root.m_next->m_next) == &m_header.m_root;
+ ipcdetail::get_pointer(m_header.m_root.m_next->m_next) == &m_header.m_root;
}
template<class MutexFamily, class VoidPointer>
@@ -328,7 +328,7 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- block_ctrl *block = detail::get_pointer(m_header.m_root.m_next);
+ block_ctrl *block = ipcdetail::get_pointer(m_header.m_root.m_next);
//Iterate through all free portions
do{
@@ -336,7 +336,7 @@
std::memset( reinterpret_cast<char*>(block) + BlockCtrlBytes
, 0
, block->m_size*Alignment - BlockCtrlBytes);
- block = detail::get_pointer(block->m_next);
+ block = ipcdetail::get_pointer(block->m_next);
}
while(block != &m_header.m_root);
}
@@ -348,14 +348,14 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- block_ctrl *block = detail::get_pointer(m_header.m_root.m_next);
+ block_ctrl *block = ipcdetail::get_pointer(m_header.m_root.m_next);
size_type free_memory = 0;
//Iterate through all blocks obtaining their size
do{
//Free blocks's next must be always valid
- block_ctrl *next = detail::get_pointer(block->m_next);
+ block_ctrl *next = ipcdetail::get_pointer(block->m_next);
if(!next){
return false;
}
@@ -497,11 +497,11 @@
}
size_type needs_backwards =
- detail::get_rounded_size(preferred_size - extra_forward, Alignment);
+ ipcdetail::get_rounded_size(preferred_size - extra_forward, Alignment);
if(!only_preferred_backwards){
needs_backwards =
- max_value(detail::get_rounded_size(min_size - extra_forward, Alignment)
+ max_value(ipcdetail::get_rounded_size(min_size - extra_forward, Alignment)
,min_value(prev->get_user_bytes(), needs_backwards));
}
@@ -562,11 +562,11 @@
return return_type(0, false);
//Number of units to request (including block_ctrl header)
- size_type nunits = detail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlSize;
+ size_type nunits = ipcdetail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlSize;
//Get the root and the first memory block
block_ctrl *prev = &m_header.m_root;
- block_ctrl *block = detail::get_pointer(prev->m_next);
+ block_ctrl *block = ipcdetail::get_pointer(prev->m_next);
block_ctrl *root = &m_header.m_root;
block_ctrl *biggest_block = 0;
block_ctrl *prev_biggest_block = 0;
@@ -595,14 +595,14 @@
if(addr) return return_type(addr, false);
//Bad luck, let's check next block
prev = block;
- block = detail::get_pointer(block->m_next);
+ block = ipcdetail::get_pointer(block->m_next);
}
//Bad luck finding preferred_size, now if we have any biggest_block
//try with this block
if(biggest_block){
received_size = biggest_block->m_size*Alignment - BlockCtrlSize;
- nunits = detail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlSize;
+ nunits = ipcdetail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlSize;
void *ret = this->priv_check_and_allocate
(nunits, prev_biggest_block, biggest_block, received_size);
if(ret)
@@ -652,12 +652,12 @@
//Take the address where the previous block should go
block_ctrl *root = &m_header.m_root;
block_ctrl *prev_2_block = root;
- block_ctrl *prev_block = detail::get_pointer(root->m_next);
+ block_ctrl *prev_block = ipcdetail::get_pointer(root->m_next);
while((reinterpret_cast<char*>(prev_block) + prev_block->m_size*Alignment)
!= (reinterpret_cast<char*>(ptr))
&& prev_block != root){
prev_2_block = prev_block;
- prev_block = detail::get_pointer(prev_block->m_next);
+ prev_block = ipcdetail::get_pointer(prev_block->m_next);
}
if(prev_block == root || !prev_block->m_next)
@@ -692,8 +692,8 @@
received_size = old_block_size*Alignment - BlockCtrlBytes;
//Now translate it to Alignment units
- min_size = detail::get_rounded_size(min_size, Alignment)/Alignment;
- preferred_size = detail::get_rounded_size(preferred_size, Alignment)/Alignment;
+ min_size = ipcdetail::get_rounded_size(min_size, Alignment)/Alignment;
+ preferred_size = ipcdetail::get_rounded_size(preferred_size, Alignment)/Alignment;
//Some parameter checks
if(min_size > preferred_size)
@@ -725,8 +725,8 @@
//Find the previous free block of next_block
block_ctrl *prev = &m_header.m_root;
- while(detail::get_pointer(prev->m_next) != next_block){
- prev = detail::get_pointer(prev->m_next);
+ while(ipcdetail::get_pointer(prev->m_next) != next_block){
+ prev = ipcdetail::get_pointer(prev->m_next);
}
//Now insert merged block in the free list
@@ -768,7 +768,7 @@
//Now translate it to Alignment units
max_size = max_size/Alignment;
- preferred_size = detail::get_rounded_size(preferred_size, Alignment)/Alignment;
+ preferred_size = ipcdetail::get_rounded_size(preferred_size, Alignment)/Alignment;
//Some parameter checks
if(max_size < preferred_size)
@@ -940,15 +940,15 @@
//This ordering comparison must be done with original pointers
//types since their mapping to raw pointers can be different
//in each process
- while((detail::get_pointer(pos) != &m_header.m_root) && (block > pos)){
+ while((ipcdetail::get_pointer(pos) != &m_header.m_root) && (block > pos)){
prev = pos;
pos = pos->m_next;
}
//Try to combine with upper block
- if ((reinterpret_cast<char*>(detail::get_pointer(block))
+ if ((reinterpret_cast<char*>(ipcdetail::get_pointer(block))
+ Alignment*block->m_size) ==
- reinterpret_cast<char*>(detail::get_pointer(pos))){
+ reinterpret_cast<char*>(ipcdetail::get_pointer(pos))){
block->m_size += pos->m_size;
block->m_next = pos->m_next;
@@ -958,9 +958,9 @@
}
//Try to combine with lower block
- if ((reinterpret_cast<char*>(detail::get_pointer(prev))
+ if ((reinterpret_cast<char*>(ipcdetail::get_pointer(prev))
+ Alignment*prev->m_size) ==
- reinterpret_cast<char*>(detail::get_pointer(block))){
+ reinterpret_cast<char*>(ipcdetail::get_pointer(block))){
prev->m_size += block->m_size;
prev->m_next = block->m_next;
}
@@ -969,7 +969,7 @@
}
}
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
Modified: branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -22,7 +22,7 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/containers/allocation_type.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -46,7 +46,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
//!This class implements the simple sequential fit algorithm with a simply
//!linked list of free buffers.
@@ -117,9 +117,9 @@
size_type m_extra_hdr_bytes;
} m_header;
- friend class detail::memory_algorithm_common<simple_seq_fit_impl>;
+ friend class ipcdetail::memory_algorithm_common<simple_seq_fit_impl>;
- typedef detail::memory_algorithm_common<simple_seq_fit_impl> algo_impl_t;
+ typedef ipcdetail::memory_algorithm_common<simple_seq_fit_impl> algo_impl_t;
public:
//!Constructor. "size" is the total size of the managed memory segment,
@@ -281,7 +281,7 @@
public:
static const size_type Alignment = ::boost::alignment_of< ::boost::detail::max_align>::value;
private:
- static const size_type BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
+ static const size_type BlockCtrlBytes = ipcdetail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
static const size_type BlockCtrlUnits = BlockCtrlBytes/Alignment;
static const size_type MinBlockUnits = BlockCtrlUnits;
static const size_type MinBlockSize = MinBlockUnits*Alignment;
@@ -303,7 +303,7 @@
size_type uint_aligned_this = uint_this/Alignment*Alignment;
size_type this_disalignment = (uint_this - uint_aligned_this);
size_type block1_off =
- detail::get_rounded_size(sizeof(simple_seq_fit_impl) + extra_hdr_bytes + this_disalignment, Alignment)
+ ipcdetail::get_rounded_size(sizeof(simple_seq_fit_impl) + extra_hdr_bytes + this_disalignment, Alignment)
- this_disalignment;
algo_impl_t::assert_alignment(this_disalignment + block1_off);
return block1_off;
@@ -319,7 +319,7 @@
size_type uint_aligned_this = uint_this/Alignment*Alignment;
size_type this_disalignment = (uint_this - uint_aligned_this);
size_type old_end =
- detail::get_truncated_size(m_header.m_size + this_disalignment, Alignment)
+ ipcdetail::get_truncated_size(m_header.m_size + this_disalignment, Alignment)
- this_disalignment;
algo_impl_t::assert_alignment(old_end + this_disalignment);
return old_end;
@@ -339,7 +339,7 @@
m_header.m_root.m_next = reinterpret_cast<block_ctrl*>
((reinterpret_cast<char*>(this) + block1_off));
- algo_impl_t::assert_alignment(detail::get_pointer(m_header.m_root.m_next));
+ algo_impl_t::assert_alignment(ipcdetail::get_pointer(m_header.m_root.m_next));
m_header.m_root.m_next->m_size = (size - block1_off)/Alignment;
m_header.m_root.m_next->m_next = &m_header.m_root;
}
@@ -384,7 +384,7 @@
//Get the root and the first memory block
block_ctrl *prev = &m_header.m_root;
block_ctrl *last = &m_header.m_root;
- block_ctrl *block = detail::get_pointer(last->m_next);
+ block_ctrl *block = ipcdetail::get_pointer(last->m_next);
block_ctrl *root = &m_header.m_root;
//No free block?
@@ -394,7 +394,7 @@
while(block != root){
prev = last;
last = block;
- block = detail::get_pointer(block->m_next);
+ block = ipcdetail::get_pointer(block->m_next);
}
char *last_free_end_address = reinterpret_cast<char*>(last) + last->m_size*Alignment;
@@ -412,7 +412,7 @@
unique_block = priv_allocate(boost::interprocess::allocate_new, 0, 0, ignore).first;
if(!unique_block)
return;
- last = detail::get_pointer(m_header.m_root.m_next);
+ last = ipcdetail::get_pointer(m_header.m_root.m_next);
BOOST_ASSERT(last_free_end_address == (reinterpret_cast<char*>(last) + last->m_size*Alignment));
}
size_type last_units = last->m_size;
@@ -493,8 +493,8 @@
simple_seq_fit_impl<MutexFamily, VoidPointer>::
get_min_size (size_type extra_hdr_bytes)
{
- return detail::get_rounded_size((size_type)sizeof(simple_seq_fit_impl),Alignment) +
- detail::get_rounded_size(extra_hdr_bytes,Alignment)
+ return ipcdetail::get_rounded_size((size_type)sizeof(simple_seq_fit_impl),Alignment) +
+ ipcdetail::get_rounded_size(extra_hdr_bytes,Alignment)
+ MinBlockSize;
}
@@ -506,7 +506,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
return m_header.m_allocated == 0 &&
- detail::get_pointer(m_header.m_root.m_next->m_next) == &m_header.m_root;
+ ipcdetail::get_pointer(m_header.m_root.m_next->m_next) == &m_header.m_root;
}
template<class MutexFamily, class VoidPointer>
@@ -515,7 +515,7 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- block_ctrl *block = detail::get_pointer(m_header.m_root.m_next);
+ block_ctrl *block = ipcdetail::get_pointer(m_header.m_root.m_next);
//Iterate through all free portions
do{
@@ -523,7 +523,7 @@
std::memset( priv_get_user_buffer(block)
, 0
, block->get_user_bytes());
- block = detail::get_pointer(block->m_next);
+ block = ipcdetail::get_pointer(block->m_next);
}
while(block != &m_header.m_root);
}
@@ -535,7 +535,7 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- block_ctrl *block = detail::get_pointer(m_header.m_root.m_next);
+ block_ctrl *block = ipcdetail::get_pointer(m_header.m_root.m_next);
size_type free_memory = 0;
@@ -545,7 +545,7 @@
if(!algo_impl_t::check_alignment(block))
return false;
//Free blocks's next must be always valid
- block_ctrl *next = detail::get_pointer(block->m_next);
+ block_ctrl *next = ipcdetail::get_pointer(block->m_next);
if(!next){
return false;
}
@@ -693,10 +693,10 @@
}
size_type needs_backwards =
- detail::get_rounded_size(preferred_size - extra_forward, Alignment);
+ ipcdetail::get_rounded_size(preferred_size - extra_forward, Alignment);
if(!only_preferred_backwards){
- max_value(detail::get_rounded_size(min_size - extra_forward, Alignment)
+ max_value(ipcdetail::get_rounded_size(min_size - extra_forward, Alignment)
,min_value(prev->get_user_bytes(), needs_backwards));
}
@@ -757,7 +757,7 @@
simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_get_total_units(size_type userbytes)
{
- size_type s = detail::get_rounded_size(userbytes, Alignment)/Alignment;
+ size_type s = ipcdetail::get_rounded_size(userbytes, Alignment)/Alignment;
if(!s) ++s;
return BlockCtrlUnits + s;
}
@@ -782,11 +782,11 @@
return return_type(static_cast<void*>(0), false);
//Number of units to request (including block_ctrl header)
- size_type nunits = detail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlUnits;
+ size_type nunits = ipcdetail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlUnits;
//Get the root and the first memory block
block_ctrl *prev = &m_header.m_root;
- block_ctrl *block = detail::get_pointer(prev->m_next);
+ block_ctrl *block = ipcdetail::get_pointer(prev->m_next);
block_ctrl *root = &m_header.m_root;
block_ctrl *biggest_block = 0;
block_ctrl *prev_biggest_block = 0;
@@ -821,13 +821,13 @@
}
//Bad luck, let's check next block
prev = block;
- block = detail::get_pointer(block->m_next);
+ block = ipcdetail::get_pointer(block->m_next);
}
//Bad luck finding preferred_size, now if we have any biggest_block
//try with this block
if(biggest_block){
- size_type limit_units = detail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlUnits;
+ size_type limit_units = ipcdetail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlUnits;
if(biggest_block->m_size < limit_units)
return return_type(static_cast<void*>(0), false);
@@ -892,13 +892,13 @@
//Take the address where the previous block should go
block_ctrl *root = &m_header.m_root;
block_ctrl *prev_2_block = root;
- block_ctrl *prev_block = detail::get_pointer(root->m_next);
+ block_ctrl *prev_block = ipcdetail::get_pointer(root->m_next);
while((reinterpret_cast<char*>(prev_block) + prev_block->m_size*Alignment)
!= reinterpret_cast<char*>(ptr)
&& prev_block != root){
prev_2_block = prev_block;
- prev_block = detail::get_pointer(prev_block->m_next);
+ prev_block = ipcdetail::get_pointer(prev_block->m_next);
}
if(prev_block == root || !prev_block->m_next)
@@ -935,8 +935,8 @@
received_size = old_block_size*Alignment - BlockCtrlBytes;
//Now translate it to Alignment units
- min_size = detail::get_rounded_size(min_size, Alignment)/Alignment;
- preferred_size = detail::get_rounded_size(preferred_size, Alignment)/Alignment;
+ min_size = ipcdetail::get_rounded_size(min_size, Alignment)/Alignment;
+ preferred_size = ipcdetail::get_rounded_size(preferred_size, Alignment)/Alignment;
//Some parameter checks
if(min_size > preferred_size)
@@ -968,8 +968,8 @@
//Find the previous free block of next_block
block_ctrl *prev = &m_header.m_root;
- while(detail::get_pointer(prev->m_next) != next_block){
- prev = detail::get_pointer(prev->m_next);
+ while(ipcdetail::get_pointer(prev->m_next) != next_block){
+ prev = ipcdetail::get_pointer(prev->m_next);
}
//Now insert merged block in the free list
@@ -1056,7 +1056,7 @@
//Pointer next always points to the first
//(lower address) block
block_ctrl * prev = &m_header.m_root;
- block_ctrl * pos = detail::get_pointer(m_header.m_root.m_next);
+ block_ctrl * pos = ipcdetail::get_pointer(m_header.m_root.m_next);
block_ctrl * block = reinterpret_cast<block_ctrl*>(priv_get_block(addr));
//All used blocks' next is marked with 0 so check it
@@ -1075,16 +1075,16 @@
//This ordering comparison must be done with original pointers
//types since their mapping to raw pointers can be different
//in each process
- while((detail::get_pointer(pos) != &m_header.m_root) && (block > pos)){
+ while((ipcdetail::get_pointer(pos) != &m_header.m_root) && (block > pos)){
prev = pos;
- pos = detail::get_pointer(pos->m_next);
+ pos = ipcdetail::get_pointer(pos->m_next);
}
//Try to combine with upper block
- char *block_char_ptr = reinterpret_cast<char*>(detail::get_pointer(block));
+ char *block_char_ptr = reinterpret_cast<char*>(ipcdetail::get_pointer(block));
if ((block_char_ptr + Alignment*block->m_size) ==
- reinterpret_cast<char*>(detail::get_pointer(pos))){
+ reinterpret_cast<char*>(ipcdetail::get_pointer(pos))){
block->m_size += pos->m_size;
block->m_next = pos->m_next;
}
@@ -1093,7 +1093,7 @@
}
//Try to combine with lower block
- if ((reinterpret_cast<char*>(detail::get_pointer(prev))
+ if ((reinterpret_cast<char*>(ipcdetail::get_pointer(prev))
+ Alignment*prev->m_size) ==
block_char_ptr){
@@ -1106,7 +1106,7 @@
}
}
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
Modified: branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -23,7 +23,7 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/interprocess/containers/allocation_type.hpp>
-#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -153,9 +153,9 @@
size_type m_size;
} m_header;
- friend class detail::memory_algorithm_common<rbtree_best_fit>;
+ friend class ipcdetail::memory_algorithm_common<rbtree_best_fit>;
- typedef detail::memory_algorithm_common<rbtree_best_fit> algo_impl_t;
+ typedef ipcdetail::memory_algorithm_common<rbtree_best_fit> algo_impl_t;
public:
/// @endcond
@@ -348,11 +348,11 @@
//Due to rbtree size optimizations, Alignment must have at least pointer alignment
BOOST_STATIC_ASSERT((Alignment >= ::boost::alignment_of<void_pointer>::value));
static const size_type AlignmentMask = (Alignment - 1);
- static const size_type BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
+ static const size_type BlockCtrlBytes = ipcdetail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
static const size_type BlockCtrlUnits = BlockCtrlBytes/Alignment;
- static const size_type AllocatedCtrlBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
+ static const size_type AllocatedCtrlBytes = ipcdetail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
static const size_type AllocatedCtrlUnits = AllocatedCtrlBytes/Alignment;
- static const size_type EndCtrlBlockBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
+ static const size_type EndCtrlBlockBytes = ipcdetail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
static const size_type EndCtrlBlockUnits = EndCtrlBlockBytes/Alignment;
static const size_type MinBlockUnits = BlockCtrlUnits;
static const size_type UsableByPreviousChunk = sizeof(size_type);
@@ -373,7 +373,7 @@
{
size_type uint_this = (std::size_t)this_ptr;
size_type main_hdr_end = uint_this + sizeof(rbtree_best_fit) + extra_hdr_bytes;
- size_type aligned_main_hdr_end = detail::get_rounded_size(main_hdr_end, Alignment);
+ size_type aligned_main_hdr_end = ipcdetail::get_rounded_size(main_hdr_end, Alignment);
size_type block1_off = aligned_main_hdr_end - uint_this;
algo_impl_t::assert_alignment(aligned_main_hdr_end);
algo_impl_t::assert_alignment(uint_this + block1_off);
@@ -979,13 +979,13 @@
if(it != m_header.m_imultiset.end()){
return return_type(this->priv_check_and_allocate
- (preferred_units, detail::get_pointer(&*it), received_size), false);
+ (preferred_units, ipcdetail::get_pointer(&*it), received_size), false);
}
if(it != m_header.m_imultiset.begin()&&
(--it)->m_size >= limit_units){
return return_type(this->priv_check_and_allocate
- (it->m_size, detail::get_pointer(&*it), received_size), false);
+ (it->m_size, ipcdetail::get_pointer(&*it), received_size), false);
}
}
@@ -1022,7 +1022,7 @@
{
if(userbytes < UsableByPreviousChunk)
userbytes = UsableByPreviousChunk;
- size_type units = detail::get_rounded_size(userbytes - UsableByPreviousChunk, Alignment)/Alignment + AllocatedCtrlUnits;
+ size_type units = ipcdetail::get_rounded_size(userbytes - UsableByPreviousChunk, Alignment)/Alignment + AllocatedCtrlUnits;
if(units < BlockCtrlUnits) units = BlockCtrlUnits;
return units;
}
Modified: branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -32,10 +32,10 @@
//!linked list of free buffers.
template<class MutexFamily, class VoidPointer>
class simple_seq_fit
- : public detail::simple_seq_fit_impl<MutexFamily, VoidPointer>
+ : public ipcdetail::simple_seq_fit_impl<MutexFamily, VoidPointer>
{
/// @cond
- typedef detail::simple_seq_fit_impl<MutexFamily, VoidPointer> base_t;
+ typedef ipcdetail::simple_seq_fit_impl<MutexFamily, VoidPointer> base_t;
/// @endcond
public:
Modified: branches/release/boost/interprocess/offset_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/offset_ptr.hpp (original)
+++ branches/release/boost/interprocess/offset_ptr.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -121,7 +121,7 @@
public:
typedef PointedType * pointer;
- typedef typename detail::
+ typedef typename ipcdetail::
add_reference<PointedType>::type reference;
typedef PointedType value_type;
typedef DifferenceType difference_type;
@@ -154,25 +154,25 @@
//!Emulates static_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
- offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, detail::static_cast_tag)
+ offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::static_cast_tag)
{ this->set_offset(static_cast<PointedType*>(r.get())); }
//!Emulates const_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
- offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, detail::const_cast_tag)
+ offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::const_cast_tag)
{ this->set_offset(const_cast<PointedType*>(r.get())); }
//!Emulates dynamic_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
- offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, detail::dynamic_cast_tag)
+ offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::dynamic_cast_tag)
{ this->set_offset(dynamic_cast<PointedType*>(r.get())); }
//!Emulates reinterpret_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
- offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, detail::reinterpret_cast_tag)
+ offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::reinterpret_cast_tag)
{ this->set_offset(reinterpret_cast<PointedType*>(r.get())); }
//!Obtains raw pointer from offset.
@@ -368,7 +368,7 @@
static_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::detail::static_cast_tag());
+ (r, boost::interprocess::ipcdetail::static_cast_tag());
}
//!Simulation of const_cast between pointers. Never throws.
@@ -377,7 +377,7 @@
const_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::detail::const_cast_tag());
+ (r, boost::interprocess::ipcdetail::const_cast_tag());
}
//!Simulation of dynamic_cast between pointers. Never throws.
@@ -386,7 +386,7 @@
dynamic_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::detail::dynamic_cast_tag());
+ (r, boost::interprocess::ipcdetail::dynamic_cast_tag());
}
//!Simulation of reinterpret_cast between pointers. Never throws.
@@ -395,7 +395,7 @@
reinterpret_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::detail::reinterpret_cast_tag());
+ (r, boost::interprocess::ipcdetail::reinterpret_cast_tag());
}
} //namespace interprocess {
@@ -448,7 +448,7 @@
{
//The offset ptr can embed one bit less than the alignment since it
//uses offset == 1 to store the null pointer.
- static const std::size_t value = ::boost::interprocess::detail::ls_zeros<OffsetAlignment>::value - 1;
+ static const std::size_t value = ::boost::interprocess::ipcdetail::ls_zeros<OffsetAlignment>::value - 1;
};
//Predeclaration
Modified: branches/release/boost/interprocess/permissions.hpp
==============================================================================
--- branches/release/boost/interprocess/permissions.hpp (original)
+++ branches/release/boost/interprocess/permissions.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -39,7 +39,7 @@
#if defined(BOOST_INTERPROCESS_WINDOWS)
-namespace detail {
+namespace ipcdetail {
template <int Dummy>
struct unrestricted_permissions_holder
@@ -50,7 +50,7 @@
template<int Dummy>
winapi::interprocess_all_access_security unrestricted_permissions_holder<Dummy>::unrestricted;
-} //namespace detail {
+} //namespace ipcdetail {
#endif //defined BOOST_INTERPROCESS_WINDOWS
@@ -105,7 +105,7 @@
{
/// @cond
#if defined (BOOST_INTERPROCESS_WINDOWS)
- m_perm = &detail::unrestricted_permissions_holder<0>::unrestricted;
+ m_perm = &ipcdetail::unrestricted_permissions_holder<0>::unrestricted;
#else
m_perm = 0666;
#endif
Modified: branches/release/boost/interprocess/segment_manager.hpp
==============================================================================
--- branches/release/boost/interprocess/segment_manager.hpp (original)
+++ branches/release/boost/interprocess/segment_manager.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -251,9 +251,9 @@
/// @cond
protected:
void * prot_anonymous_construct
- (size_type num, bool dothrow, detail::in_place_interface &table)
+ (size_type num, bool dothrow, ipcdetail::in_place_interface &table)
{
- typedef detail::block_header<size_type> block_header_t;
+ typedef ipcdetail::block_header<size_type> block_header_t;
block_header_t block_info ( size_type(table.size*num)
, size_type(table.alignment)
, anonymous_type
@@ -274,7 +274,7 @@
}
//Build scoped ptr to avoid leaks with constructor exception
- detail::mem_algo_deallocator<MemoryAlgorithm> mem(ptr_struct, *this);
+ ipcdetail::mem_algo_deallocator<MemoryAlgorithm> mem(ptr_struct, *this);
//Now construct the header
block_header_t * hdr = new(ptr_struct) block_header_t(block_info);
@@ -282,7 +282,7 @@
ptr = hdr->value();
//Now call constructors
- detail::array_construct(ptr, num, table);
+ ipcdetail::array_construct(ptr, num, table);
//All constructors successful, we don't want erase memory
mem.release();
@@ -290,11 +290,11 @@
}
//!Calls the destructor and makes an anonymous deallocate
- void prot_anonymous_destroy(const void *object, detail::in_place_interface &table)
+ void prot_anonymous_destroy(const void *object, ipcdetail::in_place_interface &table)
{
//Get control data from associated with this object
- typedef detail::block_header<size_type> block_header_t;
+ typedef ipcdetail::block_header<size_type> block_header_t;
block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment);
//-------------------------------
@@ -358,22 +358,22 @@
/// @cond
private:
- typedef detail::block_header<size_type> block_header_t;
- typedef detail::index_config<CharType, MemoryAlgorithm> index_config_named;
- typedef detail::index_config<char, MemoryAlgorithm> index_config_unique;
+ typedef ipcdetail::block_header<size_type> block_header_t;
+ typedef ipcdetail::index_config<CharType, MemoryAlgorithm> index_config_named;
+ typedef ipcdetail::index_config<char, MemoryAlgorithm> index_config_unique;
typedef IndexType<index_config_named> index_type;
- typedef detail::bool_<is_intrusive_index<index_type>::value > is_intrusive_t;
- typedef detail::bool_<is_node_index<index_type>::value> is_node_index_t;
+ typedef ipcdetail::bool_<is_intrusive_index<index_type>::value > is_intrusive_t;
+ typedef ipcdetail::bool_<is_node_index<index_type>::value> is_node_index_t;
public:
typedef IndexType<index_config_named> named_index_t;
typedef IndexType<index_config_unique> unique_index_t;
- typedef detail::char_ptr_holder<CharType> char_ptr_holder_t;
- typedef detail::segment_manager_iterator_transform
+ typedef ipcdetail::char_ptr_holder<CharType> char_ptr_holder_t;
+ typedef ipcdetail::segment_manager_iterator_transform
<typename named_index_t::const_iterator
,is_intrusive_index<index_type>::value> named_transform;
- typedef detail::segment_manager_iterator_transform
+ typedef ipcdetail::segment_manager_iterator_transform
<typename unique_index_t::const_iterator
,is_intrusive_index<index_type>::value> unique_transform;
/// @endcond
@@ -391,14 +391,14 @@
template<class T>
struct construct_proxy
{
- typedef detail::named_proxy<segment_manager, T, false> type;
+ typedef ipcdetail::named_proxy<segment_manager, T, false> type;
};
//!Constructor proxy object definition helper class
template<class T>
struct construct_iter_proxy
{
- typedef detail::named_proxy<segment_manager, T, true> type;
+ typedef ipcdetail::named_proxy<segment_manager, T, true> type;
};
/// @endcond
@@ -426,7 +426,7 @@
//!and the object count. On failure the first member of the
//!returned pair is 0.
template <class T>
- std::pair<T*, size_type> find (const detail::unique_instance_t* name)
+ std::pair<T*, size_type> find (const ipcdetail::unique_instance_t* name)
{ return this->priv_find_impl<T>(name, true); }
//!Tries to find a previous named allocation. Returns the address
@@ -440,7 +440,7 @@
//!and the object count. On failure the first member of the
//!returned pair is 0. This search is not mutex-protected!
template <class T>
- std::pair<T*, size_type> find_no_lock (const detail::unique_instance_t* name)
+ std::pair<T*, size_type> find_no_lock (const ipcdetail::unique_instance_t* name)
{ return this->priv_find_impl<T>(name, false); }
//!Returns throwing "construct" proxy
@@ -525,9 +525,9 @@
//!Destroys a previously created unique instance.
//!Returns false if the object was not present.
template <class T>
- bool destroy(const detail::unique_instance_t *)
+ bool destroy(const ipcdetail::unique_instance_t *)
{
- detail::placement_destroy<T> dtor;
+ ipcdetail::placement_destroy<T> dtor;
return this->priv_generic_named_destroy<char>
(typeid(T).name(), m_header.m_unique_index, dtor, is_intrusive_t());
}
@@ -537,7 +537,7 @@
template <class T>
bool destroy(const CharType *name)
{
- detail::placement_destroy<T> dtor;
+ ipcdetail::placement_destroy<T> dtor;
return this->priv_generic_named_destroy<CharType>
(name, m_header.m_named_index, dtor, is_intrusive_t());
}
@@ -548,8 +548,8 @@
void destroy_ptr(const T *p)
{
//If T is void transform it to char
- typedef typename detail::char_if_void<T>::type data_t;
- detail::placement_destroy<data_t> dtor;
+ typedef typename ipcdetail::char_if_void<T>::type data_t;
+ ipcdetail::placement_destroy<data_t> dtor;
priv_destroy_ptr(p, dtor);
}
@@ -701,7 +701,7 @@
size_type num,
bool try2find,
bool dothrow,
- detail::in_place_interface &table)
+ ipcdetail::in_place_interface &table)
{
return static_cast<T*>
(priv_generic_construct(name, num, try2find, dothrow, table));
@@ -716,7 +716,7 @@
{
//The name can't be null, no anonymous object can be found by name
BOOST_ASSERT(name != 0);
- detail::placement_destroy<T> table;
+ ipcdetail::placement_destroy<T> table;
size_type size;
void *ret;
@@ -733,9 +733,9 @@
//!and the object count. On failure the first member of the
//!returned pair is 0.
template <class T>
- std::pair<T*, size_type> priv_find__impl (const detail::unique_instance_t* name, bool lock)
+ std::pair<T*, size_type> priv_find__impl (const ipcdetail::unique_instance_t* name, bool lock)
{
- detail::placement_destroy<T> table;
+ ipcdetail::placement_destroy<T> table;
size_type size;
void *ret = priv_generic_find<char>(name, m_header.m_unique_index, table, size, is_intrusive_t(), lock);
return std::pair<T*, size_type>(static_cast<T*>(ret), size);
@@ -745,7 +745,7 @@
size_type num,
bool try2find,
bool dothrow,
- detail::in_place_interface &table)
+ ipcdetail::in_place_interface &table)
{
void *ret;
//Security overflow check
@@ -769,7 +769,7 @@
return ret;
}
- void priv_destroy_ptr(const void *ptr, detail::in_place_interface &dtor)
+ void priv_destroy_ptr(const void *ptr, ipcdetail::in_place_interface &dtor)
{
block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr, dtor.size, dtor.alignment);
switch(ctrl_data->alloc_type()){
@@ -838,22 +838,22 @@
template <class CharT>
void *priv_generic_find
(const CharT* name,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table,
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table,
size_type &length,
- detail::true_ is_intrusive,
+ ipcdetail::true_ is_intrusive,
bool use_lock)
{
(void)is_intrusive;
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
- typedef detail::index_key<CharT, void_pointer> index_key_t;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef ipcdetail::index_key<CharT, void_pointer> index_key_t;
typedef typename index_type::iterator index_it;
//-------------------------------
scoped_lock<rmutex> guard(priv_get_lock(use_lock));
//-------------------------------
//Find name in index
- detail::intrusive_compare_key<CharT> key
+ ipcdetail::intrusive_compare_key<CharT> key
(name, std::char_traits<CharT>::length(name));
index_it it = index.find(key);
@@ -878,14 +878,14 @@
template <class CharT>
void *priv_generic_find
(const CharT* name,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table,
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table,
size_type &length,
- detail::false_ is_intrusive,
+ ipcdetail::false_ is_intrusive,
bool use_lock)
{
(void)is_intrusive;
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
typedef typename index_type::key_type key_type;
typedef typename index_type::iterator index_it;
@@ -903,7 +903,7 @@
if(it != index.end()){
//Get header
block_header_t *ctrl_data = reinterpret_cast<block_header_t*>
- (detail::get_pointer(it->second.m_ptr));
+ (ipcdetail::get_pointer(it->second.m_ptr));
//Sanity check
BOOST_ASSERT((ctrl_data->m_value_bytes % table.size) == 0);
@@ -917,12 +917,12 @@
template <class CharT>
bool priv_generic_named_destroy
(block_header_t *block_header,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table,
- detail::true_ is_node_index)
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table,
+ ipcdetail::true_ is_node_index)
{
(void)is_node_index;
- typedef typename IndexType<detail::index_config<CharT, MemoryAlgorithm> >::iterator index_it;
+ typedef typename IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> >::iterator index_it;
index_it *ihdr = block_header_t::template to_first_header<index_it>(block_header);
return this->priv_generic_named_destroy_impl<CharT>(*ihdr, index, table);
@@ -931,9 +931,9 @@
template <class CharT>
bool priv_generic_named_destroy
(block_header_t *block_header,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table,
- detail::false_ is_node_index)
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table,
+ ipcdetail::false_ is_node_index)
{
(void)is_node_index;
CharT *name = static_cast<CharT*>(block_header->template name<CharT>());
@@ -942,13 +942,13 @@
template <class CharT>
bool priv_generic_named_destroy(const CharT *name,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table,
- detail::true_ is_intrusive_index)
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table,
+ ipcdetail::true_ is_intrusive_index)
{
(void)is_intrusive_index;
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
- typedef detail::index_key<CharT, void_pointer> index_key_t;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef ipcdetail::index_key<CharT, void_pointer> index_key_t;
typedef typename index_type::iterator index_it;
typedef typename index_type::value_type intrusive_value_type;
@@ -956,7 +956,7 @@
scoped_lock<rmutex> guard(m_header);
//-------------------------------
//Find name in index
- detail::intrusive_compare_key<CharT> key
+ ipcdetail::intrusive_compare_key<CharT> key
(name, std::char_traits<CharT>::length(name));
index_it it = index.find(key);
@@ -993,12 +993,12 @@
template <class CharT>
bool priv_generic_named_destroy(const CharT *name,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table,
- detail::false_ is_intrusive_index)
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table,
+ ipcdetail::false_ is_intrusive_index)
{
(void)is_intrusive_index;
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
typedef typename index_type::iterator index_it;
typedef typename index_type::key_type key_type;
@@ -1020,16 +1020,16 @@
template <class CharT>
bool priv_generic_named_destroy_impl
- (const typename IndexType<detail::index_config<CharT, MemoryAlgorithm> >::iterator &it,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::in_place_interface &table)
+ (const typename IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> >::iterator &it,
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::in_place_interface &table)
{
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
typedef typename index_type::iterator index_it;
//Get allocation parameters
block_header_t *ctrl_data = reinterpret_cast<block_header_t*>
- (detail::get_pointer(it->second.m_ptr));
+ (ipcdetail::get_pointer(it->second.m_ptr));
char *stored_name = static_cast<char*>(static_cast<void*>(const_cast<CharT*>(it->first.name())));
(void)stored_name;
@@ -1073,9 +1073,9 @@
size_type num,
bool try2find,
bool dothrow,
- detail::in_place_interface &table,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::true_ is_intrusive)
+ ipcdetail::in_place_interface &table,
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::true_ is_intrusive)
{
(void)is_intrusive;
std::size_t namelen = std::char_traits<CharT>::length(name);
@@ -1086,7 +1086,7 @@
, sizeof(CharT)
, namelen);
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
typedef typename index_type::iterator index_it;
typedef std::pair<index_it, bool> index_ib;
@@ -1110,7 +1110,7 @@
typedef typename index_type::value_type intrusive_value_type;
BOOST_TRY{
- detail::intrusive_compare_key<CharT> key(name, namelen);
+ ipcdetail::intrusive_compare_key<CharT> key(name, namelen);
insert_ret = index.insert_check(key, commit_data);
}
//Ignore exceptions
@@ -1176,7 +1176,7 @@
//Avoid constructions if constructor is trivial
//Build scoped ptr to avoid leaks with constructor exception
- detail::mem_algo_deallocator<segment_manager_base_type> mem
+ ipcdetail::mem_algo_deallocator<segment_manager_base_type> mem
(buffer_ptr, *static_cast<segment_manager_base_type*>(this));
//Initialize the node value_eraser to erase inserted node
@@ -1186,7 +1186,7 @@
value_eraser<index_type> v_eraser(index, it);
//Construct array, this can throw
- detail::array_construct(ptr, num, table);
+ ipcdetail::array_construct(ptr, num, table);
//Release rollbacks since construction was successful
v_eraser.release();
@@ -1202,9 +1202,9 @@
size_type num,
bool try2find,
bool dothrow,
- detail::in_place_interface &table,
- IndexType<detail::index_config<CharT, MemoryAlgorithm> > &index,
- detail::false_ is_intrusive)
+ ipcdetail::in_place_interface &table,
+ IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
+ ipcdetail::false_ is_intrusive)
{
(void)is_intrusive;
std::size_t namelen = std::char_traits<CharT>::length(name);
@@ -1215,7 +1215,7 @@
, sizeof(CharT)
, namelen);
- typedef IndexType<detail::index_config<CharT, MemoryAlgorithm> > index_type;
+ typedef IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > index_type;
typedef typename index_type::key_type key_type;
typedef typename index_type::mapped_type mapped_type;
typedef typename index_type::value_type value_type;
@@ -1255,7 +1255,7 @@
if(!insert_ret.second){
if(try2find){
block_header_t *hdr = static_cast<block_header_t*>
- (detail::get_pointer(it->second.m_ptr));
+ (ipcdetail::get_pointer(it->second.m_ptr));
return hdr->value();
}
return 0;
@@ -1309,11 +1309,11 @@
it->second.m_ptr = hdr;
//Build scoped ptr to avoid leaks with constructor exception
- detail::mem_algo_deallocator<segment_manager_base_type> mem
+ ipcdetail::mem_algo_deallocator<segment_manager_base_type> mem
(buffer_ptr, *static_cast<segment_manager_base_type*>(this));
//Construct array, this can throw
- detail::array_construct(ptr, num, table);
+ ipcdetail::array_construct(ptr, num, table);
//All constructors successful, we don't want to release memory
mem.release();
Modified: branches/release/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- branches/release/boost/interprocess/shared_memory_object.hpp (original)
+++ branches/release/boost/interprocess/shared_memory_object.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -63,24 +63,24 @@
//!Creates a shared memory object with name "name" and mode "mode", with the access mode "mode"
//!If the file previously exists, throws an error.*/
shared_memory_object(create_only_t, const char *name, mode_t mode, const permissions &perm = permissions())
- { this->priv_open_or_create(detail::DoCreate, name, mode, perm); }
+ { this->priv_open_or_create(ipcdetail::DoCreate, name, mode, perm); }
//!Tries to create a shared memory object with name "name" and mode "mode", with the
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
//!Otherwise throws an error.
shared_memory_object(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
- { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode, perm); }
+ { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
//!Tries to open a shared memory object with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
shared_memory_object(open_only_t, const char *name, mode_t mode)
- { this->priv_open_or_create(detail::DoOpen, name, mode, permissions()); }
+ { this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
//!Moves the ownership of "moved"'s shared memory object to *this.
//!After the call, "moved" does not represent any shared memory object.
//!Does not throw
shared_memory_object(BOOST_RV_REF(shared_memory_object) moved)
- : m_handle(file_handle_t(detail::invalid_file()))
+ : m_handle(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s shared memory to *this.
@@ -132,7 +132,7 @@
void priv_close();
//!Closes a previously opened file mapping. Never throws.
- bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
+ bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
file_handle_t m_handle;
mode_t m_mode;
@@ -143,7 +143,7 @@
/// @cond
inline shared_memory_object::shared_memory_object()
- : m_handle(file_handle_t(detail::invalid_file()))
+ : m_handle(file_handle_t(ipcdetail::invalid_file()))
{}
inline shared_memory_object::~shared_memory_object()
@@ -154,7 +154,7 @@
{ return m_filename.c_str(); }
inline bool shared_memory_object::get_size(offset_t &size) const
-{ return detail::get_file_size((file_handle_t)m_handle, size); }
+{ return ipcdetail::get_file_size((file_handle_t)m_handle, size); }
inline void shared_memory_object::swap(shared_memory_object &other)
{
@@ -165,7 +165,7 @@
inline mapping_handle_t shared_memory_object::get_mapping_handle() const
{
- return detail::mapping_handle_from_file_handle(m_handle);
+ return ipcdetail::mapping_handle_from_file_handle(m_handle);
}
inline mode_t shared_memory_object::get_mode() const
@@ -174,11 +174,11 @@
#if !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
inline bool shared_memory_object::priv_open_or_create
- (detail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm)
+ (ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm)
{
m_filename = filename;
std::string shmfile;
- detail::create_tmp_and_clean_old_and_get_filename(filename, shmfile);
+ ipcdetail::create_tmp_and_clean_old_and_get_filename(filename, shmfile);
//Set accesses
if (mode != read_write && mode != read_only){
@@ -187,14 +187,14 @@
}
switch(type){
- case detail::DoOpen:
- m_handle = detail::open_existing_file(shmfile.c_str(), mode, true);
+ case ipcdetail::DoOpen:
+ m_handle = ipcdetail::open_existing_file(shmfile.c_str(), mode, true);
break;
- case detail::DoCreate:
- m_handle = detail::create_new_file(shmfile.c_str(), mode, perm, true);
+ case ipcdetail::DoCreate:
+ m_handle = ipcdetail::create_new_file(shmfile.c_str(), mode, perm, true);
break;
- case detail::DoOpenOrCreate:
- m_handle = detail::create_or_open_file(shmfile.c_str(), mode, perm, true);
+ case ipcdetail::DoOpenOrCreate:
+ m_handle = ipcdetail::create_or_open_file(shmfile.c_str(), mode, perm, true);
break;
default:
{
@@ -204,7 +204,7 @@
}
//Check for error
- if(m_handle == detail::invalid_file()){
+ if(m_handle == ipcdetail::invalid_file()){
error_info err = system_error_code();
this->priv_close();
throw interprocess_exception(err);
@@ -219,8 +219,8 @@
try{
//Make sure a temporary path is created for shared memory
std::string shmfile;
- detail::tmp_filename(filename, shmfile);
- return detail::delete_file(shmfile.c_str());
+ ipcdetail::tmp_filename(filename, shmfile);
+ return ipcdetail::delete_file(shmfile.c_str());
}
catch(...){
return false;
@@ -229,7 +229,7 @@
inline void shared_memory_object::truncate(offset_t length)
{
- if(!detail::truncate_file(m_handle, length)){
+ if(!ipcdetail::truncate_file(m_handle, length)){
error_info err = system_error_code();
throw interprocess_exception(err);
}
@@ -237,9 +237,9 @@
inline void shared_memory_object::priv_close()
{
- if(m_handle != detail::invalid_file()){
- detail::close_file(m_handle);
- m_handle = detail::invalid_file();
+ if(m_handle != ipcdetail::invalid_file()){
+ ipcdetail::close_file(m_handle);
+ m_handle = ipcdetail::invalid_file();
}
}
@@ -268,22 +268,22 @@
} //shared_memory_object_detail
inline bool shared_memory_object::priv_open_or_create
- (detail::create_enum_t type,
+ (ipcdetail::create_enum_t type,
const char *filename,
mode_t mode, const permissions &perm)
{
#if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
const bool add_leading_slash = false;
#elif defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
- const bool add_leading_slash = !shared_memory_object_detail::use_filesistem_based_posix();
+ const bool add_leading_slash = !shared_memory_object_ipcdetail::use_filesistem_based_posix();
#else
const bool add_leading_slash = true;
#endif
if(add_leading_slash){
- detail::add_leading_slash(filename, m_filename);
+ ipcdetail::add_leading_slash(filename, m_filename);
}
else{
- detail::create_tmp_and_clean_old_and_get_filename(filename, m_filename);
+ ipcdetail::create_tmp_and_clean_old_and_get_filename(filename, m_filename);
}
//Create new mapping
@@ -301,13 +301,13 @@
int unix_perm = perm.get_permissions();
switch(type){
- case detail::DoOpen:
+ case ipcdetail::DoOpen:
{
//No oflag addition
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
}
break;
- case detail::DoCreate:
+ case ipcdetail::DoCreate:
{
oflag |= (O_CREAT | O_EXCL);
m_handle = shm_open(m_filename.c_str(), oflag, unix_perm);
@@ -316,7 +316,7 @@
}
}
break;
- case detail::DoOpenOrCreate:
+ case ipcdetail::DoOpenOrCreate:
{
oflag |= O_CREAT;
//We need a loop to change permissions correctly using fchmod, since
@@ -361,15 +361,15 @@
#if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
const bool add_leading_slash = false;
#elif defined(BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY)
- const bool add_leading_slash = !shared_memory_object_detail::use_filesistem_based_posix();
+ const bool add_leading_slash = !shared_memory_object_ipcdetail::use_filesistem_based_posix();
#else
const bool add_leading_slash = true;
#endif
if(add_leading_slash){
- detail::add_leading_slash(filename, file_str);
+ ipcdetail::add_leading_slash(filename, file_str);
}
else{
- detail::tmp_filename(filename, file_str);
+ ipcdetail::tmp_filename(filename, file_str);
}
return 0 == shm_unlink(file_str.c_str());
}
Modified: branches/release/boost/interprocess/smart_ptr/deleter.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/deleter.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/deleter.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -51,7 +51,7 @@
{}
void operator()(const pointer &p)
- { mp_mngr->destroy_ptr(detail::get_pointer(p)); }
+ { mp_mngr->destroy_ptr(ipcdetail::get_pointer(p)); }
};
} //namespace interprocess {
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -33,7 +33,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
template<class T, class VoidAllocator, class Deleter>
class weak_count;
@@ -92,7 +92,7 @@
deallocator(m_pi, alloc);
//It's more correct to use VoidAllocator::construct but
//this needs copy constructor and we don't like it
- new(detail::get_pointer(m_pi))counted_impl(p, a, d);
+ new(ipcdetail::get_pointer(m_pi))counted_impl(p, a, d);
deallocator.release();
}
}
@@ -177,7 +177,7 @@
}
void swap(shared_count & r) // nothrow
- { detail::do_swap(m_px, r.m_px); detail::do_swap(m_pi, r.m_pi); }
+ { ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); }
long use_count() const // nothrow
{ return m_pi != 0? m_pi->use_count(): 0; }
@@ -288,7 +288,7 @@
}
void swap(weak_count & r) // nothrow
- { detail::do_swap(m_px, r.m_px); detail::do_swap(m_pi, r.m_pi); }
+ { ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); }
long use_count() const // nothrow
{ return m_pi != 0? m_pi->use_count() : 0; }
@@ -310,7 +310,7 @@
bool operator<(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
{ return a.internal_less(b); }
-} // namespace detail
+} // namespace ipcdetail
} // namespace interprocess
} // namespace boost
Modified: branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -32,7 +32,7 @@
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
class sp_counted_base
{
@@ -54,7 +54,7 @@
void add_ref_copy()
{
- detail::atomic_inc32( &use_count_ );
+ ipcdetail::atomic_inc32( &use_count_ );
}
bool add_ref_lock() // true on success
@@ -63,25 +63,25 @@
{
boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ );
if( tmp == 0 ) return false;
- if( detail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp )
+ if( ipcdetail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp )
return true;
}
}
bool ref_release() // nothrow
- { return 1 == detail::atomic_dec32( &use_count_ ); }
+ { return 1 == ipcdetail::atomic_dec32( &use_count_ ); }
void weak_add_ref() // nothrow
- { detail::atomic_inc32( &weak_count_ ); }
+ { ipcdetail::atomic_inc32( &weak_count_ ); }
bool weak_release() // nothrow
- { return 1 == detail::atomic_dec32( &weak_count_ ); }
+ { return 1 == ipcdetail::atomic_dec32( &weak_count_ ); }
long use_count() const // nothrow
{ return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }
};
-} // namespace detail
+} // namespace ipcdetail
} // namespace interprocess
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -32,7 +32,7 @@
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
@@ -40,10 +40,10 @@
struct scoped_ptr_dealloc_functor
{
typedef typename Allocator::pointer pointer;
- typedef detail::integral_constant<unsigned,
+ typedef ipcdetail::integral_constant<unsigned,
boost::interprocess::version<Allocator>::value> alloc_version;
- typedef detail::integral_constant<unsigned, 1> allocator_v1;
- typedef detail::integral_constant<unsigned, 2> allocator_v2;
+ typedef ipcdetail::integral_constant<unsigned, 1> allocator_v1;
+ typedef ipcdetail::integral_constant<unsigned, 2> allocator_v2;
private:
void priv_deallocate(const typename Allocator::pointer &p, allocator_v1)
@@ -115,7 +115,7 @@
scoped_ptr< this_type, scoped_ptr_dealloc_functor<this_allocator> >
deleter(this_ptr, a_copy);
typedef typename this_allocator::value_type value_type;
- detail::get_pointer(this_ptr)->~value_type();
+ ipcdetail::get_pointer(this_ptr)->~value_type();
}
void release() // nothrow
@@ -135,7 +135,7 @@
};
-} // namespace detail
+} // namespace ipcdetail
} // namespace interprocess
Modified: branches/release/boost/interprocess/smart_ptr/enable_shared_from_this.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/enable_shared_from_this.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/enable_shared_from_this.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -53,14 +53,14 @@
shared_ptr<T, A, D> shared_from_this()
{
shared_ptr<T, A, D> p(_internal_weak_this);
- BOOST_ASSERT(detail::get_pointer(p.get()) == this);
+ BOOST_ASSERT(ipcdetail::get_pointer(p.get()) == this);
return p;
}
shared_ptr<T const, A, D> shared_from_this() const
{
shared_ptr<T const, A, D> p(_internal_weak_this);
- BOOST_ASSERT(detail::get_pointer(p.get()) == this);
+ BOOST_ASSERT(ipcdetail::get_pointer(p.get()) == this);
return p;
}
Modified: branches/release/boost/interprocess/smart_ptr/intrusive_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/intrusive_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/intrusive_ptr.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -72,7 +72,7 @@
//!Does not throw
intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p)
{
- if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(detail::get_pointer(m_ptr));
+ if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(ipcdetail::get_pointer(m_ptr));
}
//!Copy constructor. Copies the internal pointer and if "p" is not
@@ -80,7 +80,7 @@
intrusive_ptr(intrusive_ptr const & rhs)
: m_ptr(rhs.m_ptr)
{
- if(m_ptr != 0) intrusive_ptr_add_ref(detail::get_pointer(m_ptr));
+ if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::get_pointer(m_ptr));
}
//!Constructor from related. Copies the internal pointer and if "p" is not
@@ -89,14 +89,14 @@
(intrusive_ptr<U, VP> const & rhs)
: m_ptr(rhs.get())
{
- if(m_ptr != 0) intrusive_ptr_add_ref(detail::get_pointer(m_ptr));
+ if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::get_pointer(m_ptr));
}
//!Destructor. If internal pointer is not 0, calls
//!intrusive_ptr_release(get_pointer(m_ptr)). Does not throw
~intrusive_ptr()
{
- if(m_ptr != 0) intrusive_ptr_release(detail::get_pointer(m_ptr));
+ if(m_ptr != 0) intrusive_ptr_release(ipcdetail::get_pointer(m_ptr));
}
//!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
@@ -162,7 +162,7 @@
//!Exchanges the contents of the two smart pointers.
//!Does not throw
void swap(intrusive_ptr & rhs)
- { detail::do_swap(m_ptr, rhs.m_ptr); }
+ { ipcdetail::do_swap(m_ptr, rhs.m_ptr); }
/// @cond
private:
Modified: branches/release/boost/interprocess/smart_ptr/scoped_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/scoped_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/scoped_ptr.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -45,14 +45,14 @@
scoped_ptr & operator=(scoped_ptr const &);
typedef scoped_ptr<T, Deleter> this_type;
- typedef typename detail::add_reference<T>::type reference;
+ typedef typename ipcdetail::add_reference<T>::type reference;
/// @endcond
public:
typedef T element_type;
typedef Deleter deleter_type;
- typedef typename detail::pointer_type<T, Deleter>::type pointer;
+ typedef typename ipcdetail::pointer_type<T, Deleter>::type pointer;
//!Provides the type of the internal stored pointer
// typedef typename boost::pointer_to_other
@@ -129,7 +129,7 @@
//!Exchanges the internal pointer and deleter with other scoped_ptr
//!Never throws.
void swap(scoped_ptr & b) // never throws
- { detail::do_swap<Deleter>(*this, b); detail::do_swap(m_ptr, b.m_ptr); }
+ { ipcdetail::do_swap<Deleter>(*this, b); ipcdetail::do_swap(m_ptr, b.m_ptr); }
/// @cond
private:
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -45,7 +45,7 @@
template<class T, class VoidAllocator, class Deleter> class weak_ptr;
template<class T, class VoidAllocator, class Deleter> class enable_shared_from_this;
-namespace detail{
+namespace ipcdetail{
template<class T, class VoidAllocator, class Deleter>
inline void sp_enable_shared_from_this
@@ -64,7 +64,7 @@
inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> const &, ...)
{}
-} // namespace detail
+} // namespace ipcdetail
//!shared_ptr stores a pointer to a dynamically allocated object.
//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
@@ -99,9 +99,9 @@
typedef T value_type;
typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, T>::type pointer;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<value_type>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<const value_type>::type const_reference;
typedef typename boost::pointer_to_other
<typename VoidAllocator::pointer, const Deleter>::type const_deleter_pointer;
@@ -126,9 +126,9 @@
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
typedef typename boost::pointer_to_other<pointer, T>::type ParameterPointer;
- BOOST_STATIC_ASSERT((detail::is_same<pointer, ParameterPointer>::value) ||
- (detail::is_pointer<pointer>::value));
- detail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, detail::get_pointer(p), detail::get_pointer(p) );
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
+ (ipcdetail::is_pointer<pointer>::value));
+ ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::get_pointer(p), ipcdetail::get_pointer(p) );
}
@@ -162,24 +162,24 @@
/// @cond
template<class Y>
- shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::static_cast_tag)
- : m_pn( pointer(static_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::static_cast_tag)
+ : m_pn( pointer(static_cast<T*>(ipcdetail::get_pointer(r.m_pn.get_pointer())))
, r.m_pn)
{}
template<class Y>
- shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::const_cast_tag)
- : m_pn( pointer(const_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::const_cast_tag)
+ : m_pn( pointer(const_cast<T*>(ipcdetail::get_pointer(r.m_pn.get_pointer())))
, r.m_pn)
{}
template<class Y>
- shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::dynamic_cast_tag)
- : m_pn( pointer(dynamic_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::dynamic_cast_tag)
+ : m_pn( pointer(dynamic_cast<T*>(ipcdetail::get_pointer(r.m_pn.get_pointer())))
, r.m_pn)
{
if(!m_pn.get_pointer()){ // need to allocate new counter -- the cast failed
- m_pn = detail::shared_count<T, VoidAllocator, Deleter>();
+ m_pn = ipcdetail::shared_count<T, VoidAllocator, Deleter>();
}
}
/// @endcond
@@ -224,8 +224,8 @@
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
typedef typename boost::pointer_to_other<Pointer, T>::type ParameterPointer;
- BOOST_STATIC_ASSERT((detail::is_same<pointer, ParameterPointer>::value) ||
- (detail::is_pointer<Pointer>::value));
+ BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
+ (ipcdetail::is_pointer<Pointer>::value));
this_type(p, a, d).swap(*this);
}
@@ -299,7 +299,7 @@
template<class T2, class A2, class Deleter2> friend class shared_ptr;
template<class T2, class A2, class Deleter2> friend class weak_ptr;
- detail::shared_count<T, VoidAllocator, Deleter> m_pn; // reference counter
+ ipcdetail::shared_count<T, VoidAllocator, Deleter> m_pn; // reference counter
/// @endcond
}; // shared_ptr
@@ -321,15 +321,15 @@
template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
-{ return shared_ptr<T, VoidAllocator, Deleter>(r, detail::static_cast_tag()); }
+{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::static_cast_tag()); }
template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
-{ return shared_ptr<T, VoidAllocator, Deleter>(r, detail::const_cast_tag()); }
+{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::const_cast_tag()); }
template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
-{ return shared_ptr<T, VoidAllocator, Deleter>(r, detail::dynamic_cast_tag()); }
+{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::dynamic_cast_tag()); }
// get_pointer() enables boost::mem_fn to recognize shared_ptr
template<class T, class VoidAllocator, class Deleter> inline
Modified: branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -38,7 +38,7 @@
/// @cond
template <class T, class D> class unique_ptr;
-namespace detail {
+namespace ipcdetail {
template <class T> struct unique_ptr_error;
@@ -48,7 +48,7 @@
typedef unique_ptr<T, D> type;
};
-} //namespace detail {
+} //namespace ipcdetail {
/// @endcond
//!Template unique_ptr stores a pointer to an object and deletes that object
@@ -83,15 +83,15 @@
{
/// @cond
struct nat {int for_bool_;};
- typedef typename detail::add_reference<D>::type deleter_reference;
- typedef typename detail::add_reference<const D>::type deleter_const_reference;
+ typedef typename ipcdetail::add_reference<D>::type deleter_reference;
+ typedef typename ipcdetail::add_reference<const D>::type deleter_const_reference;
/// @endcond
public:
typedef T element_type;
typedef D deleter_type;
- typedef typename detail::pointer_type<T, D>::type pointer;
+ typedef typename ipcdetail::pointer_type<T, D>::type pointer;
//!Requires: D must be default constructible, and that construction must not
//!throw an exception. D must not be a reference type.
@@ -128,9 +128,9 @@
//!
//!Throws: nothing.
unique_ptr(pointer p
- ,typename detail::if_<detail::is_reference<D>
+ ,typename ipcdetail::if_<ipcdetail::is_reference<D>
,D
- ,typename detail::add_reference<const D>::type>::type d)
+ ,typename ipcdetail::add_reference<const D>::type>::type d)
: ptr_(p, d)
{}
@@ -176,12 +176,12 @@
//!Throws: nothing.
template <class U, class E>
unique_ptr(BOOST_RV_REF_2_TEMPL_ARGS(unique_ptr, U, E) u,
- typename detail::enable_if_c<
- detail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
- detail::is_convertible<E, D>::value &&
+ typename ipcdetail::enable_if_c<
+ ipcdetail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
+ ipcdetail::is_convertible<E, D>::value &&
(
- !detail::is_reference<D>::value ||
- detail::is_same<D, E>::value
+ !ipcdetail::is_reference<D>::value ||
+ ipcdetail::is_same<D, E>::value
)
,
nat
@@ -255,7 +255,7 @@
//!Requires: get() != 0.
//!Returns: *get().
//!Throws: nothing.
- typename detail::add_reference<T>::type operator*() const
+ typename ipcdetail::add_reference<T>::type operator*() const
{ return *ptr_.first(); }
//!Requires: get() != 0.
@@ -327,10 +327,10 @@
boost::compressed_pair<pointer, D> ptr_;
BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
template <class U, class E> unique_ptr(unique_ptr<U, E>&);
- template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
+ template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&);
- template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
+ template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
/// @endcond
};
/*
@@ -338,12 +338,12 @@
class unique_ptr<T[], D>
{
struct nat {int for_bool_;};
- typedef typename detail::add_reference<D>::type deleter_reference;
- typedef typename detail::add_reference<const D>::type deleter_const_reference;
+ typedef typename ipcdetail::add_reference<D>::type deleter_reference;
+ typedef typename ipcdetail::add_reference<const D>::type deleter_const_reference;
public:
typedef T element_type;
typedef D deleter_type;
- typedef typename detail::pointer_type<T, D>::type pointer;
+ typedef typename ipcdetail::pointer_type<T, D>::type pointer;
// constructors
unique_ptr() : ptr_(pointer()) {}
@@ -351,7 +351,7 @@
unique_ptr(pointer p, typename if_<
boost::is_reference<D>,
D,
- typename detail::add_reference<const D>::type>::type d)
+ typename ipcdetail::add_reference<const D>::type>::type d)
: ptr_(p, d) {}
unique_ptr(const unique_ptr& u)
: ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
@@ -374,7 +374,7 @@
}
// observers
- typename detail::add_reference<T>::type operator[](std::size_t i) const {return ptr_.first()[i];}
+ typename ipcdetail::add_reference<T>::type operator[](std::size_t i) const {return ptr_.first()[i];}
pointer get() const {return ptr_.first();}
deleter_reference get_deleter() {return ptr_.second();}
deleter_const_reference get_deleter() const {return ptr_.second();}
@@ -406,22 +406,22 @@
typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
unique_ptr(unique_ptr&);
- template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
+ template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
unique_ptr& operator=(unique_ptr&);
- template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
+ template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
};
template <class T, class D, std::size_t N>
class unique_ptr<T[N], D>
{
struct nat {int for_bool_;};
- typedef typename detail::add_reference<D>::type deleter_reference;
- typedef typename detail::add_reference<const D>::type deleter_const_reference;
+ typedef typename ipcdetail::add_reference<D>::type deleter_reference;
+ typedef typename ipcdetail::add_reference<const D>::type deleter_const_reference;
public:
typedef T element_type;
typedef D deleter_type;
- typedef typename detail::pointer_type<T, D>::type pointer;
+ typedef typename ipcdetail::pointer_type<T, D>::type pointer;
static const std::size_t size = N;
// constructors
@@ -430,7 +430,7 @@
unique_ptr(pointer p, typename if_<
boost::is_reference<D>,
D,
- typename detail::add_reference<const D>::type>::type d)
+ typename ipcdetail::add_reference<const D>::type>::type d)
: ptr_(p, d) {}
unique_ptr(const unique_ptr& u)
: ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter()) {}
@@ -453,7 +453,7 @@
}
// observers
- typename detail::add_reference<T>::type operator[](std::size_t i) const {return ptr_.first()[i];}
+ typename ipcdetail::add_reference<T>::type operator[](std::size_t i) const {return ptr_.first()[i];}
pointer get() const {return ptr_.first();}
deleter_reference get_deleter() {return ptr_.second();}
deleter_const_reference get_deleter() const {return ptr_.second();}
@@ -485,10 +485,10 @@
typename boost::enable_if<boost::is_convertible<U, pointer> >::type* = 0);
unique_ptr(unique_ptr&);
- template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
+ template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
unique_ptr& operator=(unique_ptr&);
- template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
+ template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
};
*/
template <class T, class D> inline
Modified: branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -56,9 +56,9 @@
typedef weak_ptr<T, A, D> this_type;
typedef typename boost::pointer_to_other
<typename A::pointer, T>::type pointer;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<T>::type reference;
- typedef typename detail::add_reference
+ typedef typename ipcdetail::add_reference
<T>::type const_reference;
/// @endcond
@@ -192,7 +192,7 @@
//!
//!Throws: nothing.
void swap(this_type & other) // never throws
- { detail::do_swap(m_pn, other.m_pn); }
+ { ipcdetail::do_swap(m_pn, other.m_pn); }
/// @cond
template<class T2, class A2, class D2>
@@ -200,7 +200,7 @@
{ return m_pn < rhs.m_pn; }
template<class Y>
- void _internal_assign(const detail::shared_count<Y, A, D> & pn2)
+ void _internal_assign(const ipcdetail::shared_count<Y, A, D> & pn2)
{
m_pn = pn2;
@@ -211,7 +211,7 @@
template<class T2, class A2, class D2> friend class shared_ptr;
template<class T2, class A2, class D2> friend class weak_ptr;
- detail::weak_count<T, A, D> m_pn; // reference counter
+ ipcdetail::weak_count<T, A, D> m_pn; // reference counter
/// @endcond
}; // weak_ptr
Modified: branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -47,19 +47,19 @@
m_enter_mut.lock();
//Return if there are no waiters
- if(!detail::atomic_read32(&m_num_waiters)) {
+ if(!ipcdetail::atomic_read32(&m_num_waiters)) {
m_enter_mut.unlock();
return;
}
//Notify that all threads should execute wait logic
- while(SLEEP != detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
- detail::thread_yield();
+ while(SLEEP != ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
+ ipcdetail::thread_yield();
}
/*
//Wait until the threads are woken
- while(SLEEP != detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), 0)){
- detail::thread_yield();
+ while(SLEEP != ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), 0)){
+ ipcdetail::thread_yield();
}
*/
//The enter interprocess_mutex will rest locked until the last waiting thread unlocks it
@@ -107,7 +107,7 @@
//We increment the waiting thread count protected so that it will be
//always constant when another thread enters the notification logic.
//The increment marks this thread as "waiting on interprocess_condition"
- detail::atomic_inc32(const_cast<boost::uint32_t*>(&m_num_waiters));
+ ipcdetail::atomic_inc32(const_cast<boost::uint32_t*>(&m_num_waiters));
//We unlock the external interprocess_mutex atomically with the increment
mut.unlock();
@@ -121,8 +121,8 @@
while(1){
//The thread sleeps/spins until a interprocess_condition commands a notification
//Notification occurred, we will lock the checking interprocess_mutex so that
- while(detail::atomic_read32(&m_command) == SLEEP){
- detail::thread_yield();
+ while(ipcdetail::atomic_read32(&m_command) == SLEEP){
+ ipcdetail::thread_yield();
//Check for timeout
if(tout_enabled){
@@ -150,12 +150,12 @@
//If a timeout occurred, the interprocess_mutex will not execute checking logic
if(tout_enabled && timed_out){
//Decrement wait count
- detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
+ ipcdetail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
unlock_enter_mut = true;
break;
}
else{
- boost::uint32_t result = detail::atomic_cas32
+ boost::uint32_t result = ipcdetail::atomic_cas32
(const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ONE);
if(result == SLEEP){
//Other thread has been notified and since it was a NOTIFY one
@@ -168,17 +168,17 @@
//so no other thread will exit.
//Decrement wait count.
unlock_enter_mut = true;
- detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
+ ipcdetail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
break;
}
else{
//If it is a NOTIFY_ALL command, all threads should return
//from do_timed_wait function. Decrement wait count.
- unlock_enter_mut = 1 == detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
+ unlock_enter_mut = 1 == ipcdetail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
//Check if this is the last thread of notify_all waiters
//Only the last thread will release the interprocess_mutex
if(unlock_enter_mut){
- detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ALL);
+ ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ALL);
}
break;
}
Modified: branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -19,25 +19,25 @@
{}
inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
-{ detail::atomic_write32(&this->m_count, boost::uint32_t(initialCount)); }
+{ ipcdetail::atomic_write32(&this->m_count, boost::uint32_t(initialCount)); }
inline void interprocess_semaphore::post()
{
- detail::atomic_inc32(&m_count);
+ ipcdetail::atomic_inc32(&m_count);
}
inline void interprocess_semaphore::wait()
{
- while(!detail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0))){
- while(detail::atomic_read32(&m_count) == 0){
- detail::thread_yield();
+ while(!ipcdetail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0))){
+ while(ipcdetail::atomic_read32(&m_count) == 0){
+ ipcdetail::thread_yield();
}
}
}
inline bool interprocess_semaphore::try_wait()
{
- return detail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0));
+ return ipcdetail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0));
}
inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
@@ -61,14 +61,14 @@
return this->try_wait();
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}while (true);
return true;
}
/*
inline int interprocess_semaphore::get_count() const
{
- return (int)detail::atomic_read32(&m_count);
+ return (int)ipcdetail::atomic_read32(&m_count);
}*/
} //namespace interprocess {
Modified: branches/release/boost/interprocess/sync/emulation/mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/mutex.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -25,7 +25,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
class emulation_mutex
{
@@ -61,19 +61,19 @@
inline void emulation_mutex::lock(void)
{
do{
- boost::uint32_t prev_s = detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
+ boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
if (m_s == 1 && prev_s == 0){
break;
}
// relinquish current timeslice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}while (true);
}
inline bool emulation_mutex::try_lock(void)
{
- boost::uint32_t prev_s = detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
+ boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
return m_s == 1 && prev_s == 0;
}
@@ -98,16 +98,16 @@
return false;
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}while (true);
return true;
}
inline void emulation_mutex::unlock(void)
-{ detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 0, 1); }
+{ ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 0, 1); }
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -17,7 +17,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
struct named_creation_functor_no_arg{};
@@ -26,7 +26,7 @@
{
typedef named_creation_functor_no_arg no_arg_t;
public:
- named_creation_functor(detail::create_enum_t type, Arg arg = Arg())
+ named_creation_functor(ipcdetail::create_enum_t type, Arg arg = Arg())
: m_creation_type(type), m_arg(arg){}
template<class ArgType>
@@ -40,11 +40,11 @@
bool operator()(void *address, std::size_t, bool created) const
{
switch(m_creation_type){
- case detail::DoOpen:
+ case ipcdetail::DoOpen:
return true;
break;
- case detail::DoCreate:
- case detail::DoOpenOrCreate:
+ case ipcdetail::DoCreate:
+ case ipcdetail::DoOpenOrCreate:
if(created){
construct<Arg>(address);
}
@@ -57,11 +57,11 @@
}
}
private:
- detail::create_enum_t m_creation_type;
+ ipcdetail::create_enum_t m_creation_type;
Arg m_arg;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/sync/emulation/recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/recursive_mutex.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -38,7 +38,7 @@
namespace boost {
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
class emulation_recursive_mutex
{
@@ -57,22 +57,22 @@
private:
emulation_mutex m_mutex;
unsigned int m_nLockCount;
- volatile detail::OS_systemwide_thread_id_t m_nOwner;
+ volatile ipcdetail::OS_systemwide_thread_id_t m_nOwner;
volatile boost::uint32_t m_s;
};
inline emulation_recursive_mutex::emulation_recursive_mutex()
- : m_nLockCount(0), m_nOwner(detail::get_invalid_systemwide_thread_id()){}
+ : m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
inline emulation_recursive_mutex::~emulation_recursive_mutex(){}
inline void emulation_recursive_mutex::lock()
{
- typedef detail::OS_systemwide_thread_id_t handle_t;
- const handle_t thr_id(detail::get_current_systemwide_thread_id());
+ typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
+ const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
handle_t old_id;
- detail::systemwide_thread_id_copy(m_nOwner, old_id);
- if(detail::equal_systemwide_thread_id(thr_id , old_id)){
+ ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
+ if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)){
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
@@ -81,18 +81,18 @@
}
else{
m_mutex.lock();
- detail::systemwide_thread_id_copy(thr_id, m_nOwner);
+ ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
}
}
inline bool emulation_recursive_mutex::try_lock()
{
- typedef detail::OS_systemwide_thread_id_t handle_t;
- handle_t thr_id(detail::get_current_systemwide_thread_id());
+ typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
+ handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
handle_t old_id;
- detail::systemwide_thread_id_copy(m_nOwner, old_id);
- if(detail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it
+ ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
+ if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
@@ -101,7 +101,7 @@
return true;
}
if(m_mutex.try_lock()){
- detail::systemwide_thread_id_copy(thr_id, m_nOwner);
+ ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
return true;
}
@@ -110,15 +110,15 @@
inline bool emulation_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
- typedef detail::OS_systemwide_thread_id_t handle_t;
+ typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
if(abs_time == boost::posix_time::pos_infin){
this->lock();
return true;
}
- const handle_t thr_id(detail::get_current_systemwide_thread_id());
+ const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
handle_t old_id;
- detail::systemwide_thread_id_copy(m_nOwner, old_id);
- if(detail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it
+ ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
+ if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) { // we own it
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
@@ -127,7 +127,7 @@
return true;
}
if(m_mutex.timed_lock(abs_time)){
- detail::systemwide_thread_id_copy(thr_id, m_nOwner);
+ ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
m_nLockCount = 1;
return true;
}
@@ -136,31 +136,31 @@
inline void emulation_recursive_mutex::unlock()
{
- typedef detail::OS_systemwide_thread_id_t handle_t;
+ typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
handle_t old_id;
- detail::systemwide_thread_id_copy(m_nOwner, old_id);
- const handle_t thr_id(detail::get_current_systemwide_thread_id());
+ ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
+ const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
(void)old_id;
(void)thr_id;
- BOOST_ASSERT(detail::equal_systemwide_thread_id(thr_id, old_id));
+ BOOST_ASSERT(ipcdetail::equal_systemwide_thread_id(thr_id, old_id));
--m_nLockCount;
if(!m_nLockCount){
- const handle_t new_id(detail::get_invalid_systemwide_thread_id());
- detail::systemwide_thread_id_copy(new_id, m_nOwner);
+ const handle_t new_id(ipcdetail::get_invalid_systemwide_thread_id());
+ ipcdetail::systemwide_thread_id_copy(new_id, m_nOwner);
m_mutex.unlock();
}
}
inline void emulation_recursive_mutex::take_ownership()
{
- typedef detail::OS_systemwide_thread_id_t handle_t;
+ typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
this->m_nLockCount = 1;
- const handle_t thr_id(detail::get_current_systemwide_thread_id());
- detail::systemwide_thread_id_copy
+ const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
+ ipcdetail::systemwide_thread_id_copy
(thr_id, m_nOwner);
}
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/file_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/file_lock.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -46,7 +46,7 @@
//!Constructs an empty file mapping.
//!Does not throw
file_lock()
- : m_file_hnd(file_handle_t(detail::invalid_file()))
+ : m_file_hnd(file_handle_t(ipcdetail::invalid_file()))
{}
//!Opens a file lock. Throws interprocess_exception if the file does not
@@ -57,7 +57,7 @@
//!After the call, "moved" does not represent any file mapping object.
//!Does not throw
file_lock(BOOST_RV_REF(file_lock) moved)
- : m_file_hnd(file_handle_t(detail::invalid_file()))
+ : m_file_hnd(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s file mapping to *this.
@@ -151,7 +151,7 @@
if(now >= abs_time) return false;
do{
- if(!detail::try_acquire_file_lock(hnd, acquired))
+ if(!ipcdetail::try_acquire_file_lock(hnd, acquired))
return false;
if(acquired)
@@ -164,7 +164,7 @@
return true;
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}
}while (true);
}
@@ -179,7 +179,7 @@
if(now >= abs_time) return false;
do{
- if(!detail::try_acquire_file_lock_sharable(hnd, acquired))
+ if(!ipcdetail::try_acquire_file_lock_sharable(hnd, acquired))
return false;
if(acquired)
@@ -192,7 +192,7 @@
return true;
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}
}while (true);
}
@@ -201,9 +201,9 @@
inline file_lock::file_lock(const char *name)
{
- m_file_hnd = detail::open_existing_file(name, read_write);
+ m_file_hnd = ipcdetail::open_existing_file(name, read_write);
- if(m_file_hnd == detail::invalid_file()){
+ if(m_file_hnd == ipcdetail::invalid_file()){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -211,15 +211,15 @@
inline file_lock::~file_lock()
{
- if(m_file_hnd != detail::invalid_file()){
- detail::close_file(m_file_hnd);
- m_file_hnd = detail::invalid_file();
+ if(m_file_hnd != ipcdetail::invalid_file()){
+ ipcdetail::close_file(m_file_hnd);
+ m_file_hnd = ipcdetail::invalid_file();
}
}
inline void file_lock::lock()
{
- if(!detail::acquire_file_lock(m_file_hnd)){
+ if(!ipcdetail::acquire_file_lock(m_file_hnd)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -228,7 +228,7 @@
inline bool file_lock::try_lock()
{
bool result;
- if(!detail::try_acquire_file_lock(m_file_hnd, result)){
+ if(!ipcdetail::try_acquire_file_lock(m_file_hnd, result)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -251,7 +251,7 @@
inline void file_lock::unlock()
{
- if(!detail::release_file_lock(m_file_hnd)){
+ if(!ipcdetail::release_file_lock(m_file_hnd)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -259,7 +259,7 @@
inline void file_lock::lock_sharable()
{
- if(!detail::acquire_file_lock_sharable(m_file_hnd)){
+ if(!ipcdetail::acquire_file_lock_sharable(m_file_hnd)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -268,7 +268,7 @@
inline bool file_lock::try_lock_sharable()
{
bool result;
- if(!detail::try_acquire_file_lock_sharable(m_file_hnd, result)){
+ if(!ipcdetail::try_acquire_file_lock_sharable(m_file_hnd, result)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
@@ -291,7 +291,7 @@
inline void file_lock::unlock_sharable()
{
- if(!detail::release_file_lock_sharable(m_file_hnd)){
+ if(!ipcdetail::release_file_lock_sharable(m_file_hnd)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -21,6 +21,7 @@
# pragma once
#endif
+#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -37,7 +38,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
namespace robust_emulation_helpers {
template<class T>
@@ -108,9 +109,9 @@
private:
#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- friend class detail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
+ friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
void take_ownership(){ mutex.take_ownership(); }
- detail::emulation_mutex mutex;
+ ipcdetail::emulation_mutex mutex;
#elif defined(BOOST_INTERPROCESS_USE_POSIX)
pthread_mutex_t m_mut;
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
@@ -128,7 +129,20 @@
inline interprocess_mutex::interprocess_mutex(){}
inline interprocess_mutex::~interprocess_mutex(){}
-inline void interprocess_mutex::lock(){ mutex.lock(); }
+inline void interprocess_mutex::lock()
+{
+#ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
+ boost::posix_time::ptime wait_time
+ = boost::posix_time::microsec_clock::universal_time()
+ + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
+ if (!mutex.timed_lock(wait_time))
+ {
+ throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
+ }
+#else
+ mutex.lock();
+#endif
+}
inline bool interprocess_mutex::try_lock(){ return mutex.try_lock(); }
inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time){ return mutex.timed_lock(abs_time); }
inline void interprocess_mutex::unlock(){ mutex.unlock(); }
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -52,7 +52,7 @@
#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
namespace robust_emulation_helpers {
template<class T>
@@ -119,8 +119,8 @@
#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
void take_ownership(){ mutex.take_ownership(); }
- friend class detail::robust_emulation_helpers::mutex_traits<interprocess_recursive_mutex>;
- detail::emulation_recursive_mutex mutex;
+ friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_recursive_mutex>;
+ ipcdetail::emulation_recursive_mutex mutex;
#else //#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
pthread_mutex_t m_mut;
#endif //#if (defined BOOST_INTERPROCESS_WINDOWS)
@@ -138,7 +138,20 @@
inline interprocess_recursive_mutex::interprocess_recursive_mutex(){}
inline interprocess_recursive_mutex::~interprocess_recursive_mutex(){}
-inline void interprocess_recursive_mutex::lock(){ mutex.lock(); }
+inline void interprocess_recursive_mutex::lock()
+{
+#ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
+ boost::posix_time::ptime wait_time
+ = boost::posix_time::microsec_clock::universal_time()
+ + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
+ if (!mutex.timed_lock(wait_time))
+ {
+ throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
+ }
+#else
+ mutex.lock();
+#endif
+}
inline bool interprocess_recursive_mutex::try_lock(){ return mutex.try_lock(); }
inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time){ return mutex.timed_lock(abs_time); }
inline void interprocess_recursive_mutex::unlock(){ mutex.unlock(); }
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -95,7 +95,7 @@
#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
volatile boost::uint32_t m_count;
#else
- detail::semaphore_wrapper m_sem;
+ ipcdetail::semaphore_wrapper m_sem;
#endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
/// @endcond
};
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -41,7 +41,7 @@
namespace interprocess {
/// @cond
-namespace detail{ class interprocess_tester; }
+namespace ipcdetail{ class interprocess_tester; }
/// @endcond
//! A global condition variable that can be created by name.
@@ -154,7 +154,7 @@
void do_wait(Lock& lock)
{
//named_condition only works with named_mutex
- BOOST_STATIC_ASSERT((detail::is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
+ BOOST_STATIC_ASSERT((ipcdetail::is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
//lock internal before unlocking external to avoid race with a notifier
scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
@@ -171,7 +171,7 @@
bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time)
{
//named_condition only works with named_mutex
- BOOST_STATIC_ASSERT((detail::is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
+ BOOST_STATIC_ASSERT((ipcdetail::is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
//lock internal before unlocking external to avoid race with a notifier
scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
if(!internal_lock) return false;
@@ -185,13 +185,13 @@
}
#endif
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- template <class T, class Arg> friend class boost::interprocess::detail::named_creation_functor;
- typedef detail::named_creation_functor<condition_holder> construct_func_t;
+ template <class T, class Arg> friend class boost::interprocess::ipcdetail::named_creation_functor;
+ typedef ipcdetail::named_creation_functor<condition_holder> construct_func_t;
/// @endcond
};
@@ -204,11 +204,11 @@
: m_shmem (create_only
,name
,sizeof(condition_holder) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoCreate)
+ ,construct_func_t(ipcdetail::DoCreate)
,perm)
{}
@@ -216,11 +216,11 @@
: m_shmem (open_or_create
,name
,sizeof(condition_holder) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoOpenOrCreate)
+ ,construct_func_t(ipcdetail::DoOpenOrCreate)
,perm)
{}
@@ -229,11 +229,11 @@
,name
,read_write
,0
- ,construct_func_t(detail::DoOpen))
+ ,construct_func_t(ipcdetail::DoOpen))
{}
inline void named_condition::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -104,17 +104,17 @@
/// @cond
private:
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- detail::named_semaphore_wrapper m_sem;
+ ipcdetail::named_semaphore_wrapper m_sem;
#else
interprocess_mutex *mutex() const
{ return static_cast<interprocess_mutex*>(m_shmem.get_user_address()); }
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- typedef detail::named_creation_functor<interprocess_mutex> construct_func_t;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::named_creation_functor<interprocess_mutex> construct_func_t;
#endif
/// @endcond
};
@@ -124,19 +124,19 @@
#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
inline named_mutex::named_mutex(create_only_t, const char *name, const permissions &perm)
- : m_sem(detail::DoCreate, name, 1, perm)
+ : m_sem(ipcdetail::DoCreate, name, 1, perm)
{}
inline named_mutex::named_mutex(open_or_create_t, const char *name, const permissions &perm)
- : m_sem(detail::DoOpenOrCreate, name, 1, perm)
+ : m_sem(ipcdetail::DoOpenOrCreate, name, 1, perm)
{}
inline named_mutex::named_mutex(open_only_t, const char *name)
- : m_sem(detail::DoOpen, name, 1, permissions())
+ : m_sem(ipcdetail::DoOpen, name, 1, permissions())
{}
inline void named_mutex::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_sem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_sem); }
inline named_mutex::~named_mutex()
{}
@@ -160,12 +160,12 @@
}
inline bool named_mutex::remove(const char *name)
-{ return detail::named_semaphore_wrapper::remove(name); }
+{ return ipcdetail::named_semaphore_wrapper::remove(name); }
#else
inline void named_mutex::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
inline named_mutex::~named_mutex()
{}
@@ -174,11 +174,11 @@
: m_shmem (create_only
,name
,sizeof(interprocess_mutex) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoCreate)
+ ,construct_func_t(ipcdetail::DoCreate)
,perm)
{}
@@ -186,11 +186,11 @@
: m_shmem (open_or_create
,name
,sizeof(interprocess_mutex) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoOpenOrCreate)
+ ,construct_func_t(ipcdetail::DoOpenOrCreate)
,perm)
{}
@@ -199,7 +199,7 @@
,name
,read_write
,0
- ,construct_func_t(detail::DoOpen))
+ ,construct_func_t(ipcdetail::DoOpen))
{}
inline void named_mutex::lock()
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -33,7 +33,7 @@
namespace interprocess {
/// @cond
-namespace detail{ class interprocess_tester; }
+namespace ipcdetail{ class interprocess_tester; }
/// @endcond
//!A recursive mutex with a global name, so it can be found from different
@@ -98,14 +98,14 @@
/// @cond
private:
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
interprocess_recursive_mutex *mutex() const
{ return static_cast<interprocess_recursive_mutex*>(m_shmem.get_user_address()); }
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- typedef detail::named_creation_functor<interprocess_recursive_mutex> construct_func_t;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::named_creation_functor<interprocess_recursive_mutex> construct_func_t;
/// @endcond
};
@@ -115,17 +115,17 @@
{}
inline void named_recursive_mutex::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
inline named_recursive_mutex::named_recursive_mutex(create_only_t, const char *name, const permissions &perm)
: m_shmem (create_only
,name
,sizeof(interprocess_recursive_mutex) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoCreate)
+ ,construct_func_t(ipcdetail::DoCreate)
,perm)
{}
@@ -133,11 +133,11 @@
: m_shmem (open_or_create
,name
,sizeof(interprocess_recursive_mutex) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoOpenOrCreate)
+ ,construct_func_t(ipcdetail::DoOpenOrCreate)
,perm)
{}
@@ -146,7 +146,7 @@
,name
,read_write
,0
- ,construct_func_t(detail::DoOpen))
+ ,construct_func_t(ipcdetail::DoOpen))
{}
inline void named_recursive_mutex::lock()
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 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -105,17 +105,17 @@
/// @cond
private:
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
- detail::named_semaphore_wrapper m_sem;
+ ipcdetail::named_semaphore_wrapper m_sem;
#else
interprocess_semaphore *semaphore() const
{ return static_cast<interprocess_semaphore*>(m_shmem.get_user_address()); }
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- typedef detail::named_creation_functor<interprocess_semaphore, int> construct_func_t;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::named_creation_functor<interprocess_semaphore, int> construct_func_t;
#endif
/// @endcond
};
@@ -126,23 +126,23 @@
inline named_semaphore::named_semaphore
(create_only_t, const char *name, unsigned int initialCount, const permissions &perm)
- : m_sem(detail::DoCreate, name, initialCount, perm)
+ : m_sem(ipcdetail::DoCreate, name, initialCount, perm)
{}
inline named_semaphore::named_semaphore
(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm)
- : m_sem(detail::DoOpenOrCreate, name, initialCount, perm)
+ : m_sem(ipcdetail::DoOpenOrCreate, name, initialCount, perm)
{}
inline named_semaphore::named_semaphore(open_only_t, const char *name)
- : m_sem(detail::DoOpen, name, 1, permissions())
+ : m_sem(ipcdetail::DoOpen, name, 1, permissions())
{}
inline named_semaphore::~named_semaphore()
{}
inline void named_semaphore::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_sem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_sem); }
inline void named_semaphore::wait()
{ m_sem.wait(); }
@@ -163,7 +163,7 @@
}
inline bool named_semaphore::remove(const char *name)
-{ return detail::named_semaphore_wrapper::remove(name); }
+{ return ipcdetail::named_semaphore_wrapper::remove(name); }
#else
@@ -171,18 +171,18 @@
{}
inline void named_semaphore::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
inline named_semaphore::named_semaphore
(create_only_t, const char *name, unsigned int initialCount, const permissions &perm)
: m_shmem (create_only
,name
,sizeof(interprocess_semaphore) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoCreate, initialCount)
+ ,construct_func_t(ipcdetail::DoCreate, initialCount)
,perm)
{}
@@ -191,11 +191,11 @@
: m_shmem (open_or_create
,name
,sizeof(interprocess_semaphore) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoOpenOrCreate, initialCount)
+ ,construct_func_t(ipcdetail::DoOpenOrCreate, initialCount)
,perm)
{}
@@ -205,7 +205,7 @@
,name
,read_write
,0
- ,construct_func_t(detail::DoOpen, 0))
+ ,construct_func_t(ipcdetail::DoOpen, 0))
{}
inline void named_semaphore::post()
Modified: branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -33,7 +33,7 @@
namespace interprocess {
/// @cond
-namespace detail{ class interprocess_tester; }
+namespace ipcdetail{ class interprocess_tester; }
/// @endcond
class named_condition;
@@ -223,14 +223,14 @@
/// @cond
private:
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
interprocess_upgradable_mutex *mutex() const
{ return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_user_address()); }
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- typedef detail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
+ ipcdetail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ typedef ipcdetail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
/// @endcond
};
@@ -244,11 +244,11 @@
: m_shmem (create_only
,name
,sizeof(interprocess_upgradable_mutex) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoCreate)
+ ,construct_func_t(ipcdetail::DoCreate)
,perm)
{}
@@ -257,11 +257,11 @@
: m_shmem (open_or_create
,name
,sizeof(interprocess_upgradable_mutex) +
- detail::managed_open_or_create_impl<shared_memory_object>::
+ ipcdetail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(detail::DoOpenOrCreate)
+ ,construct_func_t(ipcdetail::DoOpenOrCreate)
,perm)
{}
@@ -271,11 +271,11 @@
,name
,read_write
,0
- ,construct_func_t(detail::DoOpen))
+ ,construct_func_t(ipcdetail::DoOpen))
{}
inline void named_upgradable_mutex::dont_close_on_destruction()
-{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+{ ipcdetail::interprocess_tester::dont_close_on_destruction(m_shmem); }
inline void named_upgradable_mutex::lock()
{ this->mutex()->lock(); }
Modified: branches/release/boost/interprocess/sync/posix/interprocess_barrier.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_barrier.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_barrier.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -19,8 +19,8 @@
{
if (count == 0)
throw std::invalid_argument("count cannot be zero.");
- detail::barrierattr_wrapper barrier_attr;
- detail::barrier_initializer barrier
+ ipcdetail::barrierattr_wrapper barrier_attr;
+ ipcdetail::barrier_initializer barrier
(m_barrier, barrier_attr, static_cast<int>(count));
barrier.release();
}
Modified: branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -68,7 +68,7 @@
inline bool interprocess_condition::do_timed_wait
(const boost::posix_time::ptime &abs_time, interprocess_mutex &mut)
{
- timespec ts = detail::ptime_to_timespec(abs_time);
+ timespec ts = ipcdetail::ptime_to_timespec(abs_time);
pthread_mutex_t* pmutex = &mut.m_mut;
int res = 0;
res = pthread_cond_timedwait(&m_condition, pmutex, &ts);
Modified: branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -24,6 +24,7 @@
// It is provided "as is" without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -37,8 +38,8 @@
inline interprocess_mutex::interprocess_mutex()
{
- detail::mutexattr_wrapper mut_attr;
- detail::mutex_initializer mut(m_mut, mut_attr);
+ ipcdetail::mutexattr_wrapper mut_attr;
+ ipcdetail::mutex_initializer mut(m_mut, mut_attr);
mut.release();
}
@@ -50,8 +51,18 @@
inline void interprocess_mutex::lock()
{
+#ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
+ boost::posix_time::ptime wait_time
+ = boost::posix_time::microsec_clock::universal_time()
+ + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
+ if (!timed_lock(wait_time))
+ {
+ throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
+ }
+#else
if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
+#endif
}
inline bool interprocess_mutex::try_lock()
@@ -70,7 +81,7 @@
}
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
- timespec ts = detail::ptime_to_timespec(abs_time);
+ timespec ts = ipcdetail::ptime_to_timespec(abs_time);
int res = pthread_mutex_timedlock(&m_mut, &ts);
if (res != 0 && res != ETIMEDOUT)
throw lock_exception();
@@ -93,7 +104,7 @@
return false;
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}while (true);
return true;
Modified: branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -38,8 +38,8 @@
inline interprocess_recursive_mutex::interprocess_recursive_mutex()
{
- detail::mutexattr_wrapper mut_attr(true);
- detail::mutex_initializer mut(m_mut, mut_attr);
+ ipcdetail::mutexattr_wrapper mut_attr(true);
+ ipcdetail::mutex_initializer mut(m_mut, mut_attr);
mut.release();
}
@@ -51,8 +51,18 @@
inline void interprocess_recursive_mutex::lock()
{
+#ifdef BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING
+ boost::posix_time::ptime wait_time
+ = boost::posix_time::microsec_clock::universal_time()
+ + boost::posix_time::milliseconds(BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS);
+ if (!timed_lock(wait_time))
+ {
+ throw interprocess_exception(timeout_when_locking_error, "Interprocess mutex timeout when locking. Possible deadlock: owner died without unlocking?");
+ }
+#else
if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
+#endif
}
inline bool interprocess_recursive_mutex::try_lock()
@@ -71,7 +81,7 @@
}
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
- timespec ts = detail::ptime_to_timespec(abs_time);
+ timespec ts = ipcdetail::ptime_to_timespec(abs_time);
int res = pthread_mutex_timedlock(&m_mut, &ts);
if (res != 0 && res != ETIMEDOUT)
throw lock_exception();
@@ -94,7 +104,7 @@
return false;
}
// relinquish current time slice
- detail::thread_yield();
+ ipcdetail::thread_yield();
}while (true);
return true;
Modified: branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -24,7 +24,7 @@
namespace boost {
namespace interprocess {
-namespace detail{
+namespace ipcdetail{
#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
@@ -157,7 +157,7 @@
#endif //#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
-}//namespace detail
+}//namespace ipcdetail
}//namespace interprocess
Modified: branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -17,7 +17,7 @@
namespace interprocess {
-namespace detail {
+namespace ipcdetail {
inline timespec ptime_to_timespec (const boost::posix_time::ptime &tm)
{
@@ -29,7 +29,7 @@
return ts;
}
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
Modified: branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -37,32 +37,32 @@
namespace interprocess {
/// @cond
-namespace detail{ class interprocess_tester; }
+namespace ipcdetail{ class interprocess_tester; }
/// @endcond
-namespace detail {
+namespace ipcdetail {
inline bool semaphore_open
- (sem_t *&handle, detail::create_enum_t type, const char *origname,
+ (sem_t *&handle, ipcdetail::create_enum_t type, const char *origname,
unsigned int count, const permissions &perm = permissions())
{
std::string name;
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
- detail::add_leading_slash(origname, name);
+ ipcdetail::add_leading_slash(origname, name);
#else
- detail::create_tmp_and_clean_old_and_get_filename(origname, name);
+ ipcdetail::create_tmp_and_clean_old_and_get_filename(origname, name);
#endif
//Create new mapping
int oflag = 0;
switch(type){
- case detail::DoOpen:
+ case ipcdetail::DoOpen:
//No addition
break;
- case detail::DoCreate:
+ case ipcdetail::DoCreate:
oflag |= (O_CREAT | O_EXCL);
break;
- case detail::DoOpenOrCreate:
+ case ipcdetail::DoOpenOrCreate:
oflag |= O_CREAT;
break;
default:
@@ -99,9 +99,9 @@
try{
std::string sem_str;
#ifndef BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
- detail::add_leading_slash(semname, sem_str);
+ ipcdetail::add_leading_slash(semname, sem_str);
#else
- detail::tmp_filename(semname, sem_str);
+ ipcdetail::tmp_filename(semname, sem_str);
#endif
return 0 == sem_unlink(sem_str.c_str());
}
@@ -160,7 +160,7 @@
inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
{
#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
- timespec tspec = detail::ptime_to_timespec(abs_time);
+ timespec tspec = ipcdetail::ptime_to_timespec(abs_time);
for (;;){
int res = sem_timedwait(handle, &tspec);
if(res == 0)
@@ -195,7 +195,7 @@
public:
named_semaphore_wrapper
- (detail::create_enum_t type, const char *name, unsigned int count, const permissions &perm = permissions())
+ (ipcdetail::create_enum_t type, const char *name, unsigned int count, const permissions &perm = permissions())
{ semaphore_open(mp_sem, type, name, count, perm); }
~named_semaphore_wrapper()
@@ -220,7 +220,7 @@
{ return semaphore_unlink(name); }
private:
- friend class detail::interprocess_tester;
+ friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
{ mp_sem = BOOST_INTERPROCESS_POSIX_SEM_FAILED; }
@@ -256,7 +256,7 @@
sem_t m_sem;
};
-} //namespace detail {
+} //namespace ipcdetail {
} //namespace interprocess {
} //namespace boost {
Modified: branches/release/boost/interprocess/sync/scoped_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/scoped_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/scoped_lock.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -141,7 +141,7 @@
//! share ownership with an upgradable_lock).
template<class T>
explicit scoped_lock(BOOST_RV_REF(upgradable_lock<T>) upgr
- , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -169,7 +169,7 @@
//! do so in a non-blocking manner.
template<class T>
scoped_lock(BOOST_RV_REF(upgradable_lock<T>) upgr, try_to_lock_type
- , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -199,7 +199,7 @@
//! then mutex transfer occurs only if it can do so in a non-blocking manner.
template<class T>
scoped_lock(BOOST_RV_REF(upgradable_lock<T>) upgr, boost::posix_time::ptime &abs_time
- , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -230,7 +230,7 @@
//! do so in a non-blocking manner.
template<class T>
scoped_lock(BOOST_RV_REF(sharable_lock<T>) shar, try_to_lock_type
- , typename detail::enable_if< detail::is_same<T, Mutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, Mutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
sharable_lock<mutex_type> &s_lock = shar;
Modified: branches/release/boost/interprocess/sync/sharable_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/sharable_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/sharable_lock.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -139,7 +139,7 @@
//! "boost::interprocess::move(lock);".*/
template<class T>
sharable_lock(BOOST_RV_REF(upgradable_lock<T>) upgr
- , typename detail::enable_if< detail::is_same<T, SharableMutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, SharableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
upgradable_lock<mutex_type> &u_lock = upgr;
@@ -162,7 +162,7 @@
//! "boost::interprocess::move(lock);".
template<class T>
sharable_lock(BOOST_RV_REF(scoped_lock<T>) scop
- , typename detail::enable_if< detail::is_same<T, SharableMutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, SharableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
scoped_lock<mutex_type> &e_lock = scop;
Modified: branches/release/boost/interprocess/sync/upgradable_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/upgradable_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/upgradable_lock.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -134,7 +134,7 @@
//! expression: "boost::interprocess::move(lock);".
template<class T>
upgradable_lock(BOOST_RV_REF(scoped_lock<T>) scop
- , typename detail::enable_if< detail::is_same<T, UpgradableMutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, UpgradableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
scoped_lock<mutex_type> &u_lock = scop;
@@ -162,7 +162,7 @@
//! occurs only if it can do so in a non-blocking manner.
template<class T>
upgradable_lock( BOOST_RV_REF(sharable_lock<T>) shar, try_to_lock_type
- , typename detail::enable_if< detail::is_same<T, UpgradableMutex> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_same<T, UpgradableMutex> >::type * = 0)
: mp_mutex(0), m_locked(false)
{
sharable_lock<mutex_type> &s_lock = shar;
Modified: branches/release/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/xsi/xsi_named_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/xsi/xsi_named_mutex.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -60,7 +60,7 @@
//!If the named mutex previously exists, it tries to open it.
//!Otherwise throws an error.
xsi_named_mutex(open_or_create_t, const char *path, boost::uint8_t id, int perm = 0666)
- { this->priv_open_or_create(detail::DoOpenOrCreate, path, id, perm); }
+ { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, path, id, perm); }
//!Moves the ownership of "moved"'s named mutex to *this.
//!After the call, "moved" does not represent any named mutex
@@ -112,7 +112,7 @@
void priv_close();
//!Closes a previously opened file mapping. Never throws.
- bool priv_open_or_create( detail::create_enum_t type
+ bool priv_open_or_create( ipcdetail::create_enum_t type
, const char *path
, boost::uint8_t id
, int perm);
@@ -152,7 +152,7 @@
{ return m_perm; }
inline bool xsi_named_mutex::priv_open_or_create
- (detail::create_enum_t type, const char *path, boost::uint8_t id, int perm)
+ (ipcdetail::create_enum_t type, const char *path, boost::uint8_t id, int perm)
{
key_t key;
if(path){
Modified: branches/release/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/windows_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/windows_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -64,18 +64,18 @@
//!with the access mode "mode".
//!If the file previously exists, throws an error.
windows_shared_memory(create_only_t, const char *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
- { this->priv_open_or_create(detail::DoCreate, name, mode, size, perm); }
+ { this->priv_open_or_create(ipcdetail::DoCreate, name, mode, size, perm); }
//!Tries to create a shared memory object with name "name" and mode "mode", with the
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
//!Otherwise throws an error.
windows_shared_memory(open_or_create_t, const char *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
- { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode, size, perm); }
+ { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, size, perm); }
//!Tries to open a shared memory object with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
windows_shared_memory(open_only_t, const char *name, mode_t mode)
- { this->priv_open_or_create(detail::DoOpen, name, mode, 0, permissions()); }
+ { this->priv_open_or_create(ipcdetail::DoOpen, name, mode, 0, permissions()); }
//!Moves the ownership of "moved"'s shared memory object to *this.
//!After the call, "moved" does not represent any shared memory object.
@@ -119,7 +119,7 @@
void priv_close();
//!Closes a previously opened file mapping. Never throws.
- bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode, std::size_t size, const permissions& perm = permissions());
+ bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, std::size_t size, const permissions& perm = permissions());
void * m_handle;
mode_t m_mode;
@@ -153,7 +153,7 @@
{ return m_mode; }
inline bool windows_shared_memory::priv_open_or_create
- (detail::create_enum_t type, const char *filename, mode_t mode, std::size_t size, const permissions& perm)
+ (ipcdetail::create_enum_t type, const char *filename, mode_t mode, std::size_t size, const permissions& perm)
{
m_name = filename ? filename : "";
@@ -183,12 +183,12 @@
}
switch(type){
- case detail::DoOpen:
+ case ipcdetail::DoOpen:
m_handle = winapi::open_file_mapping
(map_access, filename);
break;
- case detail::DoCreate:
- case detail::DoOpenOrCreate:
+ case ipcdetail::DoCreate:
+ case ipcdetail::DoOpenOrCreate:
{
__int64 s = size;
unsigned long high_size(s >> 32), low_size((boost::uint32_t)s);
@@ -204,7 +204,7 @@
}
}
- if(!m_handle || (type == detail::DoCreate && winapi::get_last_error() == winapi::error_already_exists)){
+ if(!m_handle || (type == ipcdetail::DoCreate && winapi::get_last_error() == winapi::error_already_exists)){
error_info err = system_error_code();
this->priv_close();
throw interprocess_exception(err);
Modified: branches/release/boost/interprocess/xsi_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/xsi_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/xsi_shared_memory.hpp 2011-08-30 11:46:15 EDT (Tue, 30 Aug 2011)
@@ -66,17 +66,17 @@
//!Creates a new XSI shared memory from 'key', with size "size" and permissions "perm".
//!If the shared memory previously exists, throws an error.
xsi_shared_memory(create_only_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions())
- { this->priv_open_or_create(detail::DoCreate, key, perm, size); }
+ { this->priv_open_or_create(ipcdetail::DoCreate, key, perm, size); }
//!Opens an existing shared memory with identifier 'key' or creates a new XSI shared memory from
//!identifier 'key', with size "size" and permissions "perm".
xsi_shared_memory(open_or_create_t, const xsi_key &key, std::size_t size, const permissions& perm = permissions())
- { this->priv_open_or_create(detail::DoOpenOrCreate, key, perm, size); }
+ { this->priv_open_or_create(ipcdetail::DoOpenOrCreate, key, perm, size); }
//!Tries to open a XSI shared memory with identifier 'key'
//!If the shared memory does not previously exist, it throws an error.
xsi_shared_memory(open_only_t, const xsi_key &key)
- { this->priv_open_or_create(detail::DoOpen, key, permissions(), 0); }
+ { this->priv_open_or_create(ipcdetail::DoOpen, key, permissions(), 0); }
//!Moves the ownership of "moved"'s shared memory object to *this.
//!After the call, "moved" does not represent any shared memory object.
@@ -119,7 +119,7 @@
private:
//!Closes a previously opened file mapping. Never throws.
- bool priv_open_or_create( detail::create_enum_t type
+ bool priv_open_or_create( ipcdetail::create_enum_t type
, const xsi_key &key
, const permissions& perm
, std::size_t size);
@@ -148,20 +148,20 @@
{ mapping_handle_t mhnd = { m_shmid, true}; return mhnd; }
inline bool xsi_shared_memory::priv_open_or_create
- (detail::create_enum_t type, const xsi_key &key, const permissions& permissions, std::size_t size)
+ (ipcdetail::create_enum_t type, const xsi_key &key, const permissions& permissions, std::size_t size)
{
int perm = permissions.get_permissions();
perm &= 0x01FF;
int shmflg = perm;
switch(type){
- case detail::DoOpen:
+ case ipcdetail::DoOpen:
shmflg |= 0;
break;
- case detail::DoCreate:
+ case ipcdetail::DoCreate:
shmflg |= IPC_CREAT | IPC_EXCL;
break;
- case detail::DoOpenOrCreate:
+ case ipcdetail::DoOpenOrCreate:
shmflg |= IPC_CREAT;
break;
default:
@@ -173,7 +173,7 @@
int ret = ::shmget(key.get_key(), size, shmflg);
int shmid = ret;
- if((type == detail::DoOpen) && (-1 != ret)){
+ if((type == ipcdetail::DoOpen) && (-1 != ret)){
//Now get the size
::shmid_ds xsi_ds;
ret = ::shmctl(ret, IPC_STAT, &xsi_ds);
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