Merged from trunk

[SVN r78115]
This commit is contained in:
Ion Gaztañaga
2012-04-21 20:36:10 +00:00
parent 166f43004a
commit ac9b5d15b4
74 changed files with 4479 additions and 1250 deletions

View File

@@ -1,6 +1,6 @@
# Boost.Container library documentation Jamfile ---------------------------------
#
# Copyright Ion Gaztanaga 2009-2011. Use, modification and
# Copyright Ion Gaztanaga 2009-2012. Use, modification and
# distribution is subject to the Boost Software License, Version
# 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
@@ -27,6 +27,8 @@ doxygen autodoc
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_RV_REF(T)=T &&\" \\
\"BOOST_RV_REF_BEG=\" \\
\"BOOST_RV_REF_END=&&\" \\
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
\"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T<a, b> &&\" \\
\"BOOST_RV_REF_3_TEMPL_ARGS(T,a,b,c)=T<a,b,c>T<a,b,c> &&\" \\

View File

@@ -1,5 +1,5 @@
[/
/ Copyright (c) 2009-2011 Ion Gazta\u00F1aga
/ Copyright (c) 2009-2012 Ion Gazta\u00F1aga
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,7 +8,7 @@
[library Boost.Container
[quickbook 1.5]
[authors [Gaztanaga, Ion]]
[copyright 2009-2011 Ion Gaztanaga]
[copyright 2009-2012 Ion Gaztanaga]
[id container]
[dirname container]
[purpose Containers library]
@@ -37,9 +37,9 @@ In short, what does [*Boost.Container] offer?
(they can be safely placed in shared memory).
* The library offers new useful containers:
* [classref boost::container::flat_map flat_map],
[classref boost::container::flat_map flat_set],
[classref boost::container::flat_map flat_multiset] and
[classref boost::container::flat_map flat_multiset]: drop-in
[classref boost::container::flat_set flat_set],
[classref boost::container::flat_multiset flat_multiset] and
[classref boost::container::flat_multiset flat_multiset]: drop-in
replacements for standard associative containers but more memory friendly and with faster
searches.
* [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid
@@ -378,7 +378,7 @@ adequate for your needs, and that you often need to use insert and erase in the
should probably use list instead of slist.]]
[*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement
insertion and implements it a bit differently for the standard C++11 `forward_list`. `forward_list` has no `size()`
insertion and implements it a bit differently than the standard C++ `forward_list`. `forward_list` has no `size()`
method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size
with every insertion/erasure, allowing constant-time
`splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers
@@ -422,10 +422,9 @@ to suppose two allocators of the same type always compare equal (that means that
by one allocator object could be deallocated by another instance of the same type) and
allocators were not swapped when the container was swapped.
C++11 further improves stateful allocator support through the
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf
Scoped Allocators model]. [@http://en.cppreference.com/w/cpp/memory/allocator_traits
`std::allocator_traits`] is the protocol between a container and an allocator, and
C++11 further improves stateful allocator support through
[@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`].
`std::allocator_traits` is the protocol between a container and an allocator, and
an allocator writer can customize its behaviour (should the container propagate it in
move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container]
not only supports this model with C++11 but also [*backports it to C++03].
@@ -437,6 +436,36 @@ not constructed on the fly when auxiliary memory is needed).
[endsect]
[section:scoped_allocator Scoped allocators]
C++11 improves stateful allocators with the introduction of
[@http://http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor `std::scoped_allocator_adaptor`]
class template. `scoped_allocator_adaptor` is instantiated with one outer allocator and zero or more inner
allocators.
A scoped allocator is a mechanism to automatically propagate the state of the allocator to the subobjects
of a container in a controlled way. If instantiated with only one allocator type, the inner allocator
becomes the `scoped_allocator_adaptor` itself, thus using the same allocator
resource for the container and every element within the container and, if the elements themselves are
containers, each of their elements recursively. If instantiated with more than one allocator, the first allocator
is the outer allocator for use by the container, the second allocator is passed to the constructors of the
container's elements, and, if the elements themselves are containers, the third allocator is passed to the
elements' elements, and so on.
[*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also
to C++03 compilers]. Due to C++03 limitations, in those compilers
the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions
will be based on traits([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix]
and [classref boost::container::constructible_with_allocator_prefix constructible_with_allocator_prefix])
proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf
N2554: The Scoped Allocator Model (Rev 2) proposal]. In conforming C++11 compilers or compilers supporting SFINAE
expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules
(`is_constructible<T, Args..., inner_allocator_type>::value` and
`is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value`)
will be used to detect if the allocator must be propagated with suffix or prefix allocator arguments.
[endsect]
[section:initializer_lists Initializer lists]
[*Boost.Container] does not support initializer lists when constructing or assigning containers
@@ -585,6 +614,21 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes]
[section:release_notes_boost_1_50_00 Boost 1.50 Release]
* Added Scoped Allocator Model support.
* Fixed bugs
[@https://svn.boost.org/trac/boost/ticket/6566 #6566],
[@https://svn.boost.org/trac/boost/ticket/6575 #6575],
[@https://svn.boost.org/trac/boost/ticket/6606 #6606],
[@https://svn.boost.org/trac/boost/ticket/6615 #6615],
[@https://svn.boost.org/trac/boost/ticket/6533 #6533],
[@https://svn.boost.org/trac/boost/ticket/6536 #6536],
[endsect]
[section:release_notes_boost_1_49_00 Boost 1.49 Release]
* Fixed bugs

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,651 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Pablo Halpern 2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-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_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_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/allocator/allocator_traits.hpp>
#include <boost/type_traits.hpp>
#include <utility>
namespace boost { namespace container {
template <typename OuterAlloc, typename... InnerAllocs>
class scoped_allocator_adaptor;
template <typename OuterAlloc, typename... InnerAllocs>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...> make_scoped();
template <typename OuterAlloc, typename... InnerAllocs>
class scoped_allocator_adaptor_base : public OuterAlloc
{
typedef allocator_traits<OuterAlloc> OuterTraits;
public:
// Workaround for inability of gcc-4.4.1 to expand InnerAllocs...
// typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
typedef decltype(make_scoped<InnerAllocs...>()) inner_allocator_type;
scoped_allocator_adaptor_base();
template <typename OuterA2>
scoped_allocator_adaptor_base(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs);
template <typename OuterA2>
scoped_allocator_adaptor_base(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other);
template <typename OuterA2>
scoped_allocator_adaptor_base(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other);
inner_allocator_type& inner_allocator()
{ return _M_inner_allocs; }
inner_allocator_type const& inner_allocator() const
{ return _M_inner_allocs; }
// Allocator propagation functions.
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
select_on_container_copy_construction() const;
typedef std::integral_constant<
bool,
OuterTraits::propagate_on_container_copy_assignment::value ||
inner_allocator_type::propagate_on_container_copy_assignment::value
> propagate_on_container_copy_assignment;
typedef std::integral_constant<
bool,
OuterTraits::propagate_on_container_move_assignment::value ||
inner_allocator_type::propagate_on_container_move_assignment::value
> propagate_on_container_move_assignment;
typedef std::integral_constant<
bool,
OuterTraits::propagate_on_container_swap::value ||
inner_allocator_type::propagate_on_container_swap::value
> propagate_on_container_swap;
private:
inner_allocator_type _M_inner_allocs;
};
// Specialization with only one parameter.
template <typename OuterAlloc>
class scoped_allocator_adaptor_base<OuterAlloc> : public OuterAlloc
{
typedef allocator_traits<OuterAlloc> OuterTraits;
public:
typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
scoped_allocator_adaptor_base();
template <typename OuterA2>
scoped_allocator_adaptor_base(OuterA2&& outerAlloc);
template <typename OuterA2>
scoped_allocator_adaptor_base(const scoped_allocator_adaptor<OuterA2>& other);
template <typename OuterA2>
scoped_allocator_adaptor_base(scoped_allocator_adaptor<OuterA2>&& other);
inner_allocator_type& inner_allocator()
{ return static_cast<inner_allocator_type&>(*this); }
inner_allocator_type const& inner_allocator() const
{ return static_cast<const inner_allocator_type&>(*this); }
// Allocator propagation functions.
scoped_allocator_adaptor<OuterAlloc>
select_on_container_copy_construction() const;
typedef typename OuterTraits::propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
typedef typename OuterTraits::propagate_on_container_move_assignment propagate_on_container_move_assignment;
typedef typename OuterTraits::propagate_on_container_swap propagate_on_container_swap;
};
template <typename OuterAlloc, typename... InnerAllocs>
class scoped_allocator_adaptor
: public scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...>
{
typedef scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...> _Base;
typedef allocator_traits<OuterAlloc> _Traits;
public:
typedef OuterAlloc outer_allocator_type;
typedef typename _Base::inner_allocator_type inner_allocator_type;
typedef typename allocator_traits<OuterAlloc>::size_type size_type;
typedef typename allocator_traits<OuterAlloc>::difference_type difference_type;
typedef typename allocator_traits<OuterAlloc>::pointer pointer;
typedef typename allocator_traits<OuterAlloc>::const_pointer const_pointer;
typedef typename allocator_traits<OuterAlloc>::void_pointer void_pointer;
typedef typename allocator_traits<OuterAlloc>::const_void_pointer const_void_pointer;
typedef typename allocator_traits<OuterAlloc>::value_type value_type;
template <typename Tp>
struct rebind {
typedef typename allocator_traits<OuterAlloc>::template rebind_traits<Tp> rebound_traits;
typedef typename rebound_traits::allocator_type rebound_outer; // exposition only
typedef scoped_allocator_adaptor<rebound_outer, InnerAllocs...> other;
};
scoped_allocator_adaptor();
scoped_allocator_adaptor(const scoped_allocator_adaptor& other);
template <typename OuterA2>
scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other);
template <typename OuterA2>
scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other);
template <typename OuterA2>
scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs);
~scoped_allocator_adaptor();
inner_allocator_type & inner_allocator()
{ return _Base::inner_allocator(); }
inner_allocator_type const& inner_allocator() const
{ return _Base::inner_allocator(); }
outer_allocator_type & outer_allocator()
{ return *this; }
outer_allocator_type const& outer_allocator() const
{ return *this; }
pointer allocate(size_type n);
pointer allocate(size_type n, const_void_pointer hint);
void deallocate(pointer p, size_type n);
size_type max_size() const;
template <typename T, typename... Args>
void construct(T* p, Args&&... args);
// Specializations to pass inner_allocator to pair::first and pair::second
template <class T1, class T2>
void construct(std::pair<T1,T2>* p);
template <class T1, class T2, class U, class V>
void construct(std::pair<T1,T2>* p, U&& x, V&& y);
template <class T1, class T2, class U, class V>
void construct(std::pair<T1,T2>* p, const std::pair<U, V>& pr);
template <class T1, class T2, class U, class V>
void construct(std::pair<T1,T2>* p, std::pair<U, V>&& pr);
template <typename T>
void destroy(T* p);
};
template <typename OuterA1, typename OuterA2, typename... InnerAllocs>
inline
bool operator==(const scoped_allocator_adaptor<OuterA1,InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2,InnerAllocs...>& b);
template <typename OuterA1, typename OuterA2, typename... InnerAllocs>
inline
bool operator!=(const scoped_allocator_adaptor<OuterA1,InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2,InnerAllocs...>& b);
///////////////////////////////////////////////////////////////////////////////
// Implementation of scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...>
///////////////////////////////////////////////////////////////////////////////
template <typename OuterAlloc, typename... InnerAllocs>
inline
scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor_base()
{
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename OuterA2>
scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor_base(OuterA2&& outerAlloc,
const InnerAllocs&... innerAllocs)
: OuterAlloc(std::forward<OuterA2>(outerAlloc))
, _M_inner_allocs(innerAllocs...)
{
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename OuterA2>
scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor_base(
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other)
: OuterAlloc(other.outer_allocator())
, _M_inner_allocs(other.inner_allocator())
{
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename OuterA2>
scoped_allocator_adaptor_base<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor_base(
scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other)
: OuterAlloc(std::move(other.outer_allocator()))
, _M_inner_allocs(std::move(other.inner_allocator()))
{
}
template <typename OuterAlloc, typename... InnerAllocs>
inline
scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>
scoped_allocator_adaptor_base<OuterAlloc,InnerAllocs...>::
select_on_container_copy_construction() const
{
return scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>(
allocator_traits<OuterAlloc>::select_on_container_copy_construction(
this->outer_allocator()),
allocator_traits<inner_allocator_type>::select_on_container_copy_construction(
this->inner_allocator()));
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of scoped_allocator_adaptor_base<OuterAlloc> specialization
///////////////////////////////////////////////////////////////////////////////
template <typename OuterAlloc>
inline
scoped_allocator_adaptor_base<OuterAlloc>::
scoped_allocator_adaptor_base()
{
}
template <typename OuterAlloc>
template <typename OuterA2>
scoped_allocator_adaptor_base<OuterAlloc>::
scoped_allocator_adaptor_base(OuterA2&& outerAlloc)
: OuterAlloc(std::forward<OuterA2>(outerAlloc))
{
}
template <typename OuterAlloc>
template <typename OuterA2>
scoped_allocator_adaptor_base<OuterAlloc>::
scoped_allocator_adaptor_base(
const scoped_allocator_adaptor<OuterA2>& other)
: OuterAlloc(other.outer_allocator())
{
}
template <typename OuterAlloc>
template <typename OuterA2>
scoped_allocator_adaptor_base<OuterAlloc>::
scoped_allocator_adaptor_base(
scoped_allocator_adaptor<OuterA2>&& other)
: OuterAlloc(std::move(other.outer_allocator()))
{
}
// template <typename OuterAlloc>
// inline
// scoped_allocator_adaptor<OuterAlloc>&
// scoped_allocator_adaptor_base<OuterAlloc>::inner_allocator()
// {
// return *this;
// }
// template <typename OuterAlloc>
// inline
// scoped_allocator_adaptor<OuterAlloc> const&
// scoped_allocator_adaptor_base<OuterAlloc>::inner_allocator() cosnt
// {
// return *this;
// }
template <typename OuterAlloc>
inline
scoped_allocator_adaptor<OuterAlloc>
scoped_allocator_adaptor_base<OuterAlloc>::
select_on_container_copy_construction() const
{
return
allocator_traits<OuterAlloc>::select_on_container_copy_construction(
this->outer_allocator());
}
///////////////////////////////////////////////////////////////////////////////
// Implementation of scoped_allocator_adaptor details
///////////////////////////////////////////////////////////////////////////////
namespace __details {
// Overload resolution for __has_ctor resolves to this function
// when _Tp is constructible with _Args. Returns true_type().
static void* __void_p; // Declared but not defined
template <typename _Tp, typename... _Args>
inline
auto __has_ctor(int, _Args&&... __args) ->
decltype((new (__void_p) _Tp(__args...), std::true_type()))
{ return std::true_type(); }
// Overload resolution for __has_ctor resolves to this function
// when _Tp is not constructible with _Args. Returns false_type().
template <typename _Tp, typename... _Args>
auto __has_ctor(_LowPriorityConversion<int>, _Args&&...) ->
std::false_type
{ return std::false_type(); }
template <typename _Alloc>
struct __is_scoped_allocator_imp {
template <typename T>
static char test(int, typename T::outer_allocator_type*);
template <typename T>
static int test(_LowPriorityConversion<int>, void*);
static const bool value = (1 == sizeof(test<_Alloc>(0, 0)));
};
template <typename _Alloc>
struct __is_scoped_allocator
: std::integral_constant<bool, __is_scoped_allocator_imp<_Alloc>::value>
{
};
#if 0
// Called when outer_allocator_type is not a scoped allocator
// (recursion stop).
template <typename _Alloc>
inline
auto __outermost_alloc(_LowPriorityConversion<int>, _Alloc& __a) ->
_Alloc&
{
return __a;
}
// Called when outer_allocator_type is a scoped allocator to
// return the outermost allocator type.
template <typename _Alloc>
inline auto __outermost_alloc(int, _Alloc& __a) ->
decltype(__outermost_alloc(0,__a.outer_allocator()))
{
return __a.outer_allocator();
}
#endif
template <typename _Ignore, typename _OuterAlloc,
typename _InnerAlloc, typename _Tp, typename... _Args>
inline void __dispatch_scoped_construct(std::false_type __uses_alloc,
_Ignore __use_alloc_prefix,
_OuterAlloc& __outer_alloc,
_InnerAlloc& __inner_alloc,
_Tp* __p, _Args&&... __args)
{
// _Tp doesn't use allocators. Construct without an
// allocator argument.
allocator_traits<_OuterAlloc>::construct(__outer_alloc, __p,
std::forward<_Args>(__args)...);
}
template <typename _OuterAlloc,
typename _InnerAlloc, typename _Tp, typename... _Args>
inline void __dispatch_scoped_construct(std::true_type __uses_alloc,
std::true_type __use_alloc_prefix,
_OuterAlloc& __outer_alloc,
_InnerAlloc& __inner_alloc,
_Tp* __p, _Args&&... __args)
{
// _Tp doesn't use allocators. Construct without an
// allocator argument.
allocator_traits<_OuterAlloc>::construct(__outer_alloc, __p,
allocator_arg, __inner_alloc,
std::forward<_Args>(__args)...);
}
template <typename _OuterAlloc,
typename _InnerAlloc, typename _Tp, typename... _Args>
inline void __dispatch_scoped_construct(std::true_type __uses_alloc,
std::false_type __use_alloc_prefix,
_OuterAlloc& __outer_alloc,
_InnerAlloc& __inner_alloc,
_Tp* __p, _Args&&... __args)
{
// If _Tp uses an allocator compatible with _InnerAlloc,
// but the specific constructor does not have a variant that
// takes an allocator argument, then program is malformed.
// static_assert(has_constructor<_Tp, _Args...>::value,
// "Cannot pass inner allocator to this constructor");
allocator_traits<_OuterAlloc>::construct(
__outer_alloc, __p, std::forward<_Args>(__args)...,
__inner_alloc);
}
template <typename _OuterAlloc, typename _InnerAlloc,
typename _Tp, typename... _Args>
inline void __do_scoped_construct(std::false_type __scoped_outer,
_OuterAlloc& __outer_alloc,
_InnerAlloc& __inner_alloc,
_Tp* __p, _Args&&... __args)
{
// Dispatch construction to the correct __dispatch_scoped_construct()
// function based on whether _Tp uses an allocator of type
// _InnerAlloc and, if so, whether there exists the following
// constructor:
// _Tp(allocator_arg_t, _InnerAlloc, Args...).
auto __uses_alloc = uses_allocator<_Tp, _InnerAlloc>();
auto __use_alloc_prefix = __has_ctor<_Tp>(0, allocator_arg,
__inner_alloc,
std::forward<_Args>(__args)...);
__dispatch_scoped_construct(__uses_alloc, __use_alloc_prefix,
__outer_alloc,
__inner_alloc,
__p, std::forward<_Args>(__args)...);
}
template <typename _OuterAlloc, typename _InnerAlloc,
typename _Tp, typename... _Args>
void __do_scoped_construct(std::true_type __scoped_outer,
_OuterAlloc& __outer_alloc,
_InnerAlloc& __inner_alloc,
_Tp* __p, _Args&&... __args)
{
// Use outermost allocator if __outer_alloc is scoped
typedef typename _OuterAlloc::outer_allocator_type outerouter;
__do_scoped_construct(__is_scoped_allocator<outerouter>(),
__outer_alloc.outer_allocator(),
__inner_alloc,
__p, std::forward<_Args>(__args)...);
}
} // end namespace __details
///////////////////////////////////////////////////////////////////////////////
// Implementation of scoped_allocator_adaptor
///////////////////////////////////////////////////////////////////////////////
template <typename OuterAlloc, typename... InnerAllocs>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor()
{
}
template <typename OuterAlloc, typename... InnerAllocs>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
: _Base(other)
{
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename OuterA2>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2,
InnerAllocs...>& other)
: _Base(other)
{
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename OuterA2>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other)
: _Base(std::move(other))
{
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename OuterA2>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs)
: _Base(std::forward<OuterA2>(outerAlloc), innerAllocs...)
{
}
template <typename OuterAlloc, typename... InnerAllocs>
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
~scoped_allocator_adaptor()
{
}
template <typename OuterAlloc, typename... InnerAllocs>
inline typename allocator_traits<OuterAlloc>::pointer
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
allocate(size_type n)
{
return allocator_traits<OuterAlloc>::allocate(outer_allocator(), n);
}
template <typename OuterAlloc, typename... InnerAllocs>
inline typename allocator_traits<OuterAlloc>::pointer
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
allocate(size_type n, const_void_pointer hint)
{
return allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint);
}
template <typename OuterAlloc, typename... InnerAllocs>
inline void scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
deallocate(pointer p, size_type n)
{
allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n);
}
template <typename OuterAlloc, typename... InnerAllocs>
inline typename allocator_traits<OuterAlloc>::size_type
scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::max_size() const
{
return allocator_traits<OuterAlloc>::max_size(outer_allocator());
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename T>
inline void scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>::
destroy(T* p)
{
allocator_traits<OuterAlloc>::destroy(outer_allocator(), p);
}
template <typename OuterAlloc, typename... InnerAllocs>
template <typename T, typename... Args>
inline
void scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>::construct(T* p,
Args&&... args)
{
__do_scoped_construct(__details::__is_scoped_allocator<OuterAlloc>(),
this->outer_allocator(), this->inner_allocator(),
p, std::forward<Args>(args)...);
}
template <typename OuterAlloc, typename... InnerAllocs>
template <class T1, class T2>
void scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>::construct(
std::pair<T1,T2>* p)
{
construct(addressof(p->first));
try {
construct(addressof(p->second));
}
catch (...) {
destroy(addressof(p->first));
throw;
}
}
template <typename OuterAlloc, typename... InnerAllocs>
template <class T1, class T2, class U, class V>
void scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>::construct(
std::pair<T1,T2>* p, U&& x, V&& y)
{
construct(addressof(p->first), std::forward<U>(x));
try {
construct(addressof(p->second), std::forward<V>(y));
}
catch (...) {
destroy(addressof(p->first));
throw;
}
}
template <typename OuterAlloc, typename... InnerAllocs>
template <class T1, class T2, class U, class V>
void scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>::construct(
std::pair<T1,T2>* p, const std::pair<U, V>& pr)
{
construct(addressof(p->first), pr.first);
try {
construct(addressof(p->second), pr.second);
}
catch (...) {
destroy(addressof(p->first));
throw;
}
}
template <typename OuterAlloc, typename... InnerAllocs>
template <class T1, class T2, class U, class V>
void scoped_allocator_adaptor<OuterAlloc,InnerAllocs...>::construct(
std::pair<T1,T2>* p, std::pair<U, V>&& pr)
{
construct(addressof(p->first), std::move(pr.first));
try {
construct(addressof(p->second), std::move(pr.second));
}
catch (...) {
destroy(addressof(p->first));
throw;
}
}
template <typename OuterA1, typename OuterA2, typename... InnerAllocs>
inline
bool operator==(const scoped_allocator_adaptor<OuterA1,InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2,InnerAllocs...>& b)
{
return a.outer_allocator() == b.outer_allocator()
&& a.inner_allocator() == b.inner_allocator();
}
template <typename OuterA1, typename OuterA2>
inline
bool operator==(const scoped_allocator_adaptor<OuterA1>& a,
const scoped_allocator_adaptor<OuterA2>& b)
{
return a.outer_allocator() == b.outer_allocator();
}
template <typename OuterA1, typename OuterA2, typename... InnerAllocs>
inline
bool operator!=(const scoped_allocator_adaptor<OuterA1,InnerAllocs...>& a,
const scoped_allocator_adaptor<OuterA2,InnerAllocs...>& b)
{
return ! (a == b);
}
}} // namespace boost { namespace container {
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP

View File

@@ -6,7 +6,7 @@
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -24,7 +24,8 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/allocator/memory_util.hpp>
#include <boost/intrusive/detail/memory_util.hpp>
#include <boost/container/detail/memory_util.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp>
@@ -53,6 +54,8 @@ struct is_std_allocator< std::allocator<T> >
///@endcond
//! The class template allocator_traits supplies a uniform interface to all allocator types.
//! This class is a C++03-compatible implementation of std::allocator_traits
template <typename Alloc>
struct allocator_traits
{
@@ -62,54 +65,54 @@ struct allocator_traits
typedef typename Alloc::value_type value_type;
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!Alloc::pointer if such a type exists; otherwise, value_type*
//!
//! Alloc::pointer if such a type exists; otherwise, value_type*
//!
typedef unspecified pointer;
//!Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
//!
//! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
//!
typedef unspecified const_pointer;
//!Non-standard extension
//!Alloc::reference if such a type exists; otherwise, value_type&
typedef unspecified pointer;
//!Non-standard extension
//!Alloc::const_reference if such a type exists ; otherwise, const value_type&
typedef unspecified const_pointer;
//!Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//!
//! Non-standard extension
//! Alloc::reference if such a type exists; otherwise, value_type&
typedef unspecified reference;
//! Non-standard extension
//! Alloc::const_reference if such a type exists ; otherwise, const value_type&
typedef unspecified const_reference;
//! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//!
typedef unspecified void_pointer;
//!Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
//!
//! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
//!
typedef unspecified const_void_pointer;
//!Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
//!
//! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
//!
typedef unspecified difference_type;
//!Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
//!
//! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
//!
typedef unspecified size_type;
//!Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
//!type with internal constant static member <pre>value</pre> == false.
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
typedef unspecified propagate_on_container_copy_assignment;
//!Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
//!type with internal constant static member <pre>value</pre> == false.
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
typedef unspecified propagate_on_container_move_assignment;
//!Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
//!type with internal constant static member <pre>value</pre> == false.
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
typedef unspecified propagate_on_container_swap;
//!Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
//!if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
//!more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
//!
//!In C++03 compilers <pre>rebind_alloc</pre> is a struct derived from an allocator
//!deduced by previously detailed rules.
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
//!
//! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
//! deduced by previously detailed rules.
template <class T> using rebind_alloc = unspecified;
//!In C++03 compilers <pre>rebind_traits</pre> is a struct derived from
//!<pre>allocator_traits<OtherAlloc><pre>, where `OtherAlloc` is
//!the allocator deduced by rules explained in `rebind_alloc`.
//! In C++03 compilers `rebind_traits` is a struct derived from
//! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
//! the allocator deduced by rules explained in `rebind_alloc`.
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
//!Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
//!`type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
//! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
template <class T>
struct portable_rebind_alloc
{ typedef unspecified_type type; };
@@ -164,9 +167,9 @@ struct allocator_traits
#if !defined(BOOST_NO_TEMPLATE_ALIASES)
//C++11
template <typename T> using rebind_alloc = boost::intrusive::detail::type_rebinder<Alloc, T>::type;
template <typename T> using rebind_alloc = typename boost::intrusive::detail::type_rebinder<Alloc, T>::type;
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
#else //!defined(BOOST_NO_TEMPLATE_ALIASES)
#else // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
//Some workaround for C++03 or C++11 compilers with no template aliases
template <typename T>
struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type
@@ -174,10 +177,10 @@ struct allocator_traits
typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base;
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <typename... Args>
rebind_alloc(Args&&... args)
rebind_alloc(BOOST_FWD_REF(Args)... args)
: Base(boost::forward<Args>(args)...)
{}
#else //!defined(BOOST_NO_VARIADIC_TEMPLATES)
#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
@@ -186,32 +189,32 @@ struct allocator_traits
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //!defined(BOOST_NO_VARIADIC_TEMPLATES)
#endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
};
template <typename T>
struct rebind_traits
: allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type>
{};
#endif //!defined(BOOST_NO_TEMPLATE_ALIASES)
#endif // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
template <class T>
struct portable_rebind_alloc
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//!<b>Returns</b>: a.allocate(n)
//!
//! <b>Returns</b>: `a.allocate(n)`
//!
static pointer allocate(Alloc &a, size_type n)
{ return a.allocate(n); }
//!<b>Returns</b>: a.deallocate(p, n)
//!
//!<b>Throws</b>: Nothing
//! <b>Returns</b>: `a.deallocate(p, n)`
//!
//! <b>Throws</b>: Nothing
static void deallocate(Alloc &a, pointer p, size_type n)
{ return a.deallocate(p, n); }
//!<b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
//!otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
{
const bool value = boost::container::container_detail::
@@ -221,8 +224,8 @@ struct allocator_traits
return allocator_traits::priv_allocate(flag, a, n, p);
}
//!<b>Effects</b>: calls a.destroy(p) if that call is well-formed;
//!otherwise, invokes `p->~T()`.
//! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
//! otherwise, invokes `p->~T()`.
template<class T>
static void destroy(Alloc &a, T*p)
{
@@ -234,8 +237,8 @@ struct allocator_traits
allocator_traits::priv_destroy(flag, a, p);
}
//!<b>Returns</b>: a.max_size() if that expression is well-formed; otherwise,
//!`numeric_limits<size_type>::max()`.
//! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise,
//! `numeric_limits<size_type>::max()`.
static size_type max_size(const Alloc &a)
{
const bool value = boost::container::container_detail::
@@ -245,8 +248,8 @@ struct allocator_traits
return allocator_traits::priv_max_size(flag, a);
}
//!<b>Returns</b>: a.select_on_container_copy_construction() if that expres sion is well- formed;
//!otherwise, a.
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
//! otherwise, a.
static Alloc select_on_container_copy_construction(const Alloc &a)
{
const bool value = boost::container::container_detail::
@@ -256,17 +259,17 @@ struct allocator_traits
return allocator_traits::priv_select_on_container_copy_construction(flag, a);
}
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!Effects: calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed;
//!otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
#if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
template <class T, class ...Args>
static void construct(Alloc & a, T* p, Args&&... args)
static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
{
::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
}
#endif
///@cond
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
private:
static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
@@ -295,9 +298,9 @@ struct allocator_traits
static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
{ return a; }
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template<class T, class ...Args>
static void priv_construct(boost::false_type, Alloc &a, T *p, Args && ...args)
static void priv_construct(boost::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_construct
@@ -307,19 +310,19 @@ struct allocator_traits
}
template<class T, class ...Args>
static void priv_construct(boost::true_type, Alloc &a, T *p, Args && ...args)
static void priv_construct(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
{
priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward<Args>(args)...);
}
template<class T, class ...Args>
static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, Args && ...args)
static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
{ a.construct( p, ::boost::forward<Args>(args)...); }
template<class T, class ...Args>
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, Args && ...args)
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
{ ::new((void*)p) T(::boost::forward<Args>(args)...); }
#else
#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
public:
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
@@ -368,7 +371,7 @@ struct allocator_traits
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //BOOST_CONTAINER_PERFECT_FORWARDING
#endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
///@endcond

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -132,26 +132,22 @@ class basic_string;
//! Type used to tag that the input range is
//! guaranteed to be ordered
struct ordered_range_impl_t {};
struct ordered_range_t
{};
//! Type used to tag that the input range is
//! guaranteed to be ordered and unique
struct ordered_unique_range_impl_t{};
/// @cond
typedef ordered_range_impl_t * ordered_range_t;
typedef ordered_unique_range_impl_t *ordered_unique_range_t;
/// @endcond
struct ordered_unique_range_t
: public ordered_range_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered
static const ordered_range_t ordered_range = 0;
static const ordered_range_t ordered_range = ordered_range_t();
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
static const ordered_unique_range_t ordered_unique_range = 0;
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
/// @cond

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -44,7 +44,7 @@
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <cstddef>
#include <iterator>
@@ -896,6 +896,46 @@ class deque : protected deque_base<T, A>
: Base(boost::move(static_cast<Base&>(x)))
{ this->swap_members(x); }
//! <b>Effects</b>: Copy constructs a vector using the specified allocator.
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Throws</b>: If allocation
//! throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
deque(const deque& x, const allocator_type &a)
: Base(a)
{
if(x.size()){
this->priv_initialize_map(x.size());
boost::container::uninitialized_copy_alloc
(this->alloc(), x.begin(), x.end(), this->members_.m_start);
}
}
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves mx's resources to *this if a == allocator_type().
//! Otherwise copies values from x to *this.
//!
//! <b>Throws</b>: If allocation or T's copy constructor throws.
//!
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
: Base(a)
{
if(mx.alloc() == a){
this->swap_members(mx);
}
else{
if(mx.size()){
this->priv_initialize_map(mx.size());
boost::container::uninitialized_copy_alloc
(this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
}
}
}
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the deque.
//!

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -17,7 +17,9 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/move/move.hpp>
#include <iterator> //std::iterator_traits
#include <boost/assert.hpp>
@@ -41,7 +43,6 @@ template<class A, class FwdIt, class Iterator>
struct advanced_insert_aux_proxy
: public advanced_insert_aux_int<Iterator>
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
@@ -54,36 +55,36 @@ struct advanced_insert_aux_proxy
{}
virtual void copy_remaining_to(Iterator p)
{ ::boost::copy_or_move(first_, last_, p); }
{ ::boost::copy_or_move(this->first_, this->last_, p); }
virtual void uninitialized_copy_remaining_to(Iterator p)
{ ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p); }
{ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
FwdIt mid = first_;
FwdIt mid = this->first_;
std::advance(mid, division_count);
if(first_n){
::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
first_ = mid;
::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
this->first_ = mid;
}
else{
::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
last_ = mid;
::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
this->last_ = mid;
}
}
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
FwdIt mid = first_;
FwdIt mid = this->first_;
std::advance(mid, division_count);
if(first_n){
::boost::copy_or_move(first_, mid, pos);
first_ = mid;
::boost::copy_or_move(this->first_, mid, pos);
this->first_ = mid;
}
else{
::boost::copy_or_move(mid, last_, pos);
last_ = mid;
::boost::copy_or_move(mid, this->last_, pos);
this->last_ = mid;
}
}
A &a_;
@@ -95,7 +96,7 @@ template<class A, class Iterator>
struct default_construct_aux_proxy
: public advanced_insert_aux_int<Iterator>
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef ::boost::container::allocator_traits<A> alloc_traits;
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
@@ -109,11 +110,11 @@ struct default_construct_aux_proxy
virtual void copy_remaining_to(Iterator)
{ //This should never be called with any count
BOOST_ASSERT(count_ == 0);
BOOST_ASSERT(this->count_ == 0);
}
virtual void uninitialized_copy_remaining_to(Iterator p)
{ this->priv_uninitialized_copy(p, count_); }
{ this->priv_uninitialized_copy(p, this->count_); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
@@ -122,22 +123,22 @@ struct default_construct_aux_proxy
new_count = division_count;
}
else{
BOOST_ASSERT(difference_type(count_)>= division_count);
new_count = count_ - division_count;
BOOST_ASSERT(difference_type(this->count_)>= division_count);
new_count = this->count_ - division_count;
}
this->priv_uninitialized_copy(pos, new_count);
}
virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
{
BOOST_ASSERT(count_ == 0);
BOOST_ASSERT(this->count_ == 0);
size_type new_count;
if(first_n){
new_count = division_count;
}
else{
BOOST_ASSERT(difference_type(count_)>= division_count);
new_count = count_ - division_count;
BOOST_ASSERT(difference_type(this->count_)>= division_count);
new_count = this->count_ - division_count;
}
//This function should never called with a count different to zero
BOOST_ASSERT(new_count == 0);
@@ -147,21 +148,21 @@ struct default_construct_aux_proxy
private:
void priv_uninitialized_copy(Iterator p, const size_type n)
{
BOOST_ASSERT(n <= count_);
BOOST_ASSERT(n <= this->count_);
Iterator orig_p = p;
size_type i = 0;
try{
for(; i < n; ++i, ++p){
alloc_traits::construct(a_, container_detail::to_raw_pointer(&*p));
alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
}
}
catch(...){
while(i--){
alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
}
throw;
}
count_ -= n;
this->count_ -= n;
}
A &a_;
size_type count_;
@@ -223,13 +224,13 @@ struct advanced_insert_aux_non_movable_emplace
{
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
alloc_traits::construct( a_
if(!this->used_){
alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail::
stored_ref<Args>::forward(get<IdxPack>(args_))...
stored_ref<Args>::forward(get<IdxPack>(this->args_))...
);
used_ = true;
this->used_ = true;
}
}
}
@@ -237,13 +238,13 @@ struct advanced_insert_aux_non_movable_emplace
template<int ...IdxPack>
void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!used_){
alloc_traits::construct( a_
if(!this->used_){
alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail::
stored_ref<Args>::forward(get<IdxPack>(args_))...
stored_ref<Args>::forward(get<IdxPack>(this->args_))...
);
used_ = true;
this->used_ = true;
}
}
@@ -260,12 +261,13 @@ struct advanced_insert_aux_emplace
: public advanced_insert_aux_non_movable_emplace<A, Iterator, Args...>
{
typedef advanced_insert_aux_non_movable_emplace<A, Iterator, Args...> base_t;
typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::index_tuple_t index_tuple_t;
explicit advanced_insert_aux_emplace(A &a, Args&&... args)
: base_t(a, boost::forward<Args>(args)...)
: base_t(a, ::boost::forward<Args>(args)...)
{}
~advanced_insert_aux_emplace()
@@ -283,8 +285,13 @@ struct advanced_insert_aux_emplace
void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!this->used_){
*p = boost::move(value_type (
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
alloc_traits::construct(this->a_, vp,
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
scoped_destructor<A> d(this->a_, vp);
*p = ::boost::move(*vp);
d.release();
this->used_ = true;
}
}
@@ -295,8 +302,17 @@ struct advanced_insert_aux_emplace
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!this->used_){
*p = boost::move(value_type(
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
alloc_traits::construct(this->a_, vp,
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
try {
*p = ::boost::move(*vp);
} catch (...) {
alloc_traits::destroy(this->a_, vp);
throw;
}
alloc_traits::destroy(this->a_, vp);
this->used_ = true;
}
}
@@ -337,13 +353,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), ar
\
virtual void uninitialized_copy_remaining_to(Iterator p) \
{ \
if(!used_){ \
if(!this->used_){ \
alloc_traits::construct \
( a_ \
( this->a_ \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
used_ = true; \
this->used_ = true; \
} \
} \
\
@@ -352,13 +368,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), ar
{ \
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \
if(!this->used_){ \
alloc_traits::construct \
( a_ \
( this->a_ \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
used_ = true; \
this->used_ = true; \
} \
} \
} \
@@ -382,6 +398,7 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > base_t; \
typedef typename base_t::value_type value_type; \
typedef typename base_t::difference_type difference_type; \
typedef boost::container::allocator_traits<A> alloc_traits; \
\
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
@@ -391,10 +408,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
virtual void copy_remaining_to(Iterator p) \
{ \
if(!this->used_){ \
value_type v BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
*p = boost::move(v); \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
alloc_traits::construct(this->a_, vp \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
scoped_destructor<A> d(this->a_, vp); \
*p = ::boost::move(*vp); \
d.release(); \
this->used_ = true; \
} \
} \
@@ -405,10 +425,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!this->used_){ \
value_type v BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
*p = boost::move(v); \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
alloc_traits::construct(this->a_, vp \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
scoped_destructor<A> d(this->a_, vp); \
*p = ::boost::move(*vp); \
d.release(); \
this->used_ = true; \
} \
} \

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -45,4 +45,5 @@
// with /GR-; unpredictable behavior may result
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
#pragma warning (disable : 4584) // X is already a base-class of Y
#endif //BOOST_MSVC

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -21,7 +21,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
namespace boost {
namespace container {
@@ -85,6 +85,9 @@ struct scoped_destructor_n
void increment_size(size_type inc)
{ m_n += inc; }
void increment_size_backwards(size_type inc)
{ m_n += inc; m_p -= inc; }
~scoped_destructor_n()
{
@@ -115,10 +118,38 @@ struct null_scoped_destructor_n
void increment_size(size_type)
{}
void increment_size_backwards(size_type)
{}
void release()
{}
};
template<class A>
class scoped_destructor
{
typedef boost::container::allocator_traits<A> AllocTraits;
public:
typedef typename A::value_type value_type;
scoped_destructor(A &a, value_type *pv)
: pv_(pv), a_(a)
{}
~scoped_destructor()
{
if(pv_){
AllocTraits::destroy(a_, pv_);
}
}
void release()
{ pv_ = 0; }
private:
value_type *pv_;
A &a_;
};
template <class Allocator>
class allocator_destroyer
{

View File

@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -102,11 +102,19 @@ class flat_tree
{}
Data(const Data &d)
: value_compare(d), m_vect(d.m_vect)
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect)
{}
Data(BOOST_RV_REF(Data) d)
: value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
{}
Data(const Data &d, const A &a)
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
{}
Data(BOOST_RV_REF(Data) d, const A &a)
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
{}
Data(const Compare &comp)
@@ -185,6 +193,14 @@ class flat_tree
: m_data(boost::move(x.m_data))
{ }
flat_tree(const flat_tree& x, const allocator_type &a)
: m_data(x.m_data, a)
{ }
flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
: m_data(boost::move(x.m_data), a)
{ }
template <class InputIterator>
flat_tree( ordered_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare()
@@ -285,7 +301,6 @@ class flat_tree
return ret;
}
iterator insert_equal(const value_type& val)
{
iterator i = this->upper_bound(KeyOfValue()(val));
@@ -323,14 +338,14 @@ class flat_tree
iterator insert_equal(const_iterator pos, const value_type& val)
{
insert_commit_data data;
priv_insert_equal_prepare(pos, val, data);
this->priv_insert_equal_prepare(pos, val, data);
return priv_insert_commit(data, val);
}
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
{
insert_commit_data data;
priv_insert_equal_prepare(pos, mval, data);
this->priv_insert_equal_prepare(pos, mval, data);
return priv_insert_commit(data, boost::move(mval));
}
@@ -346,7 +361,15 @@ class flat_tree
{
typedef typename
std::iterator_traits<InIt>::iterator_category ItCat;
priv_insert_equal(first, last, ItCat());
this->priv_insert_equal(first, last, ItCat());
}
template <class InIt>
void insert_equal(ordered_range_t, InIt first, InIt last)
{
typedef typename
std::iterator_traits<InIt>::iterator_category ItCat;
this->priv_insert_equal(ordered_range_t(), first, last, ItCat());
}
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -390,7 +413,7 @@ class flat_tree
{
value_type &&val = value_type(boost::forward<Args>(args)...);
insert_commit_data data;
priv_insert_equal_prepare(hint, val, data);
this->priv_insert_equal_prepare(hint, val, data);
return priv_insert_commit(data, boost::move(val));
}
@@ -450,7 +473,7 @@ class flat_tree
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \
insert_commit_data data; \
priv_insert_equal_prepare(hint, val, data); \
this->priv_insert_equal_prepare(hint, val, data); \
return priv_insert_commit(data, boost::move(val)); \
} \
//!
@@ -730,10 +753,39 @@ class flat_tree
return std::pair<RanIt, RanIt>(first, first);
}
template <class FwdIt>
void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
template <class BidirIt>
void priv_insert_equal(ordered_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
{
size_type len = static_cast<size_type>(std::distance(first, last));
const size_type BurstSize = 16;
size_type positions[BurstSize];
while(len){
const size_type burst = len < BurstSize ? len : BurstSize;
len -= burst;
const iterator beg(this->cbegin());
iterator pos;
for(size_type i = 0; i != burst; ++i){
pos = this->upper_bound(KeyOfValue()(*first));
positions[i] = static_cast<size_type>(pos - beg);
++first;
}
this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
}
}
template <class FwdIt>
void priv_insert_equal_forward(ordered_range_t, FwdIt first, FwdIt last, std::forward_iterator_tag)
{ this->priv_insert_equal(first, last, std::forward_iterator_tag()); }
template <class InIt>
void priv_insert_equal(ordered_range_t, InIt first, InIt last, std::input_iterator_tag)
{ this->priv_insert_equal(first, last, std::input_iterator_tag()); }
template <class FwdIt>
void priv_insert_equal_forward(FwdIt first, FwdIt last, std::forward_iterator_tag)
{
const size_type len = static_cast<size_type>(std::distance(first, last));
this->reserve(this->size()+len);
this->priv_insert_equal(first, last, std::input_iterator_tag());
}

View File

@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011.
// (C) Copyright Ion Gaztanaga 2009-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
@@ -21,7 +21,7 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
@@ -513,7 +513,7 @@ struct emplace_functor
container_detail::tuple<Args&...> args_;
};
#else
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template <) \
@@ -522,16 +522,16 @@ struct emplace_functor
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
{ \
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
\
template<class A, class T> \
void operator()(A &a, T *ptr) \
{ \
allocator_traits<A>::construct \
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
} \
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)

View File

@@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Stephen Cleary 2000.
// (C) Copyright Ion Gaztanaga 2007-2011.
// (C) Copyright Ion Gaztanaga 2007-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -27,7 +27,7 @@
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp>
@@ -36,6 +36,7 @@
#endif
#include <boost/container/detail/algorithms.hpp>
#include <new>
namespace boost {
@@ -259,47 +260,21 @@ struct node_alloc_holder
void deallocate_one(const NodePtr &p, allocator_v2)
{ this->node_alloc().deallocate_one(p); }
/*
template<class A, class Convertible1, class Convertible2>
static void construct(A &a, const NodePtr &ptr,
BOOST_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
{
typedef typename Node::hook_type hook_type;
typedef typename Node::value_type::first_type first_type;
typedef typename Node::value_type::second_type second_type;
Node *nodeptr = container_detail::to_raw_pointer(ptr);
//Hook constructor does not throw
allocator_traits<A>::construct(a, static_cast<hook_type*>(nodeptr));
//Now construct pair members_holder
value_type *valueptr = &nodeptr->get_data();
allocator_traits<A>::construct(a, &valueptr->first, boost::move(value.first));
BOOST_TRY{
allocator_traits<A>::construct(a, &valueptr->second, boost::move(value.second));
}
BOOST_CATCH(...){
allocator_traits<A>::destroy(a, &valueptr->first);
BOOST_RETHROW
}
BOOST_CATCH_END
}
*/
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
/*
template<class A, class ...Args>
static void construct(A &a, const NodePtr &ptr, Args &&...args)
{
}
*/
template<class ...Args>
NodePtr create_node(Args &&...args)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward<Args>(args)...);
( this->node_alloc()
, container_detail::addressof(p->m_data), boost::forward<Args>(args)...);
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
}
@@ -313,9 +288,11 @@ struct node_alloc_holder
NodePtr p = this->allocate_one(); \
Deallocator node_deallocator(p, this->node_alloc()); \
allocator_traits<NodeAlloc>::construct \
(this->node_alloc(), container_detail::to_raw_pointer(p) \
(this->node_alloc(), container_detail::addressof(p->m_data) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
node_deallocator.release(); \
typedef typename Node::hook_type hook_type; \
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type; \
return (p); \
} \
//!
@@ -329,8 +306,11 @@ struct node_alloc_holder
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
}
@@ -364,8 +344,11 @@ struct node_alloc_holder
mem.pop_front();
//This can throw
constructed = 0;
boost::container::construct_in_place(this->node_alloc(), p, beg);
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
++constructed;
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
//This can throw in some containers (predicate might throw)
inserter(*p);
}

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,8 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
@@ -62,6 +64,33 @@ struct pair_nat;
struct piecewise_construct_t { };
static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
/*
template <class T1, class T2>
struct pair
{
template <class U, class V> pair(pair<U, V>&& p);
template <class... Args1, class... Args2>
pair(piecewise_construct_t, tuple<Args1...> first_args,
tuple<Args2...> second_args);
template <class U, class V> pair& operator=(const pair<U, V>& p);
pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
is_nothrow_move_assignable<T2>::value);
template <class U, class V> pair& operator=(pair<U, V>&& p);
void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
noexcept(swap(second, p.second)));
};
template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&);
template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&);
template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&);
template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
*/
template <class T1, class T2>
struct pair
{
@@ -79,47 +108,40 @@ struct pair
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)
pair(const pair<D, S> &p)
: first(p.first), second(p.second)
{}
template <class D, class S>
pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second))
{}
//std::pair copy constructor
//pair from two values
pair(const T1 &t1, const T2 &t2)
: first(t1)
, second(t2)
{}
template<class U, class V>
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
: first(::boost::forward<U>(u))
, second(::boost::forward<V>(v))
{}
//And now compatibility with std::pair
pair(const std::pair<T1, T2>& x)
: first(x.first), second(x.second)
{}
@@ -129,17 +151,20 @@ struct pair
: first(p.first), second(p.second)
{}
//std::pair move constructor
template <class D, class S>
pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second))
{}
pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
template <class D, class S>
pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
: first(::boost::move(p.first)), second(::boost::move(p.second))
{}
//piecewise_construct missing
//template <class U, class V> pair(pair<U, V>&& p);
//template <class... Args1, class... Args2>
// pair(piecewise_construct_t, tuple<Args1...> first_args,
// tuple<Args2...> second_args);
/*
//Variadic versions
template<class U>
@@ -179,14 +204,6 @@ struct pair
return *this;
}
template <class D, class S>
pair& operator=(const pair<D, S>&p)
{
first = p.first;
second = p.second;
return *this;
}
//pair move assignment
pair& operator=(BOOST_RV_REF(pair) p)
{
@@ -196,7 +213,23 @@ struct pair
}
template <class D, class S>
pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
typename ::boost::container::container_detail::enable_if_c
< !(::boost::container::container_detail::is_same<T1, D>::value &&
::boost::container::container_detail::is_same<T2, S>::value)
, pair &>::type
operator=(const pair<D, S>&p)
{
first = p.first;
second = p.second;
return *this;
}
template <class D, class S>
typename ::boost::container::container_detail::enable_if_c
< !(::boost::container::container_detail::is_same<T1, D>::value &&
::boost::container::container_detail::is_same<T2, S>::value)
, pair &>::type
operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
@@ -220,7 +253,7 @@ struct pair
}
//std::pair move assignment
pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);
@@ -228,7 +261,7 @@ struct pair
}
template <class D, class S>
pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
{
first = ::boost::move(p.first);
second = ::boost::move(p.second);

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -62,6 +62,10 @@
//!
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
//!
#ifndef BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM(U, u) \
U && u \
@@ -74,17 +78,16 @@
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
//!
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
#else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
//!
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
//!
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
@@ -127,7 +130,7 @@
#else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
//!
#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
@@ -140,11 +143,11 @@
#define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
::boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
//!
#define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
@@ -152,7 +155,11 @@ BOOST_PP_CAT(*this->m_p, n) \
//!
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
BOOST_PP_CAT(class P, n) = void \
BOOST_PP_CAT(class P, n) = void \
//!
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
BOOST_PP_CAT(class P, n) = default_type \
//!
#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -27,7 +27,7 @@
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -90,70 +90,38 @@ struct rbtree_hook
>::type type;
};
//This trait is used to type-pun std::pair because in C++03
//compilers std::pair is useless for C++11 features
template<class T>
struct rbtree_type
struct rbtree_internal_data_type
{
typedef T type;
};
template<class T1, class T2>
struct rbtree_type< std::pair<T1, T2> >
struct rbtree_internal_data_type< std::pair<T1, T2> >
{
typedef pair<T1, T2> type;
};
//The node to be store in the tree
template <class T, class VoidPointer>
struct rbtree_node
: public rbtree_hook<VoidPointer>::type
{
private:
BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
//BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
rbtree_node();
public:
typedef typename rbtree_hook<VoidPointer>::type hook_type;
typedef T value_type;
typedef typename rbtree_type<T>::type internal_type;
typedef typename rbtree_internal_data_type<T>::type internal_type;
typedef rbtree_node<T, VoidPointer> node_type;
rbtree_node()
: m_data()
{}
rbtree_node(const rbtree_node &other)
: m_data(other.m_data)
{}
rbtree_node(BOOST_RV_REF(rbtree_node) other)
: m_data(boost::move(other.m_data))
{}
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
template<class ...Args>
rbtree_node(Args &&...args)
: m_data(boost::forward<Args>(args)...)
{}
#endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
rbtree_node &operator=(const rbtree_node &other)
{ do_assign(other.m_data); return *this; }
rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
{ do_move(other.m_data); return *this; }
T &get_data()
{
T* ptr = reinterpret_cast<T*>(&this->m_data);
@@ -166,7 +134,6 @@ struct rbtree_node
return *ptr;
}
private:
internal_type m_data;
template<class A, class B>
@@ -188,22 +155,22 @@ struct rbtree_node
{ m_data = v; }
template<class A, class B>
void do_move(std::pair<const A, B> &p)
void do_move_assign(std::pair<const A, B> &p)
{
const_cast<A&>(m_data.first) = boost::move(p.first);
m_data.second = boost::move(p.second);
const_cast<A&>(m_data.first) = ::boost::move(p.first);
m_data.second = ::boost::move(p.second);
}
template<class A, class B>
void do_move(pair<const A, B> &p)
void do_move_assign(pair<const A, B> &p)
{
const_cast<A&>(m_data.first) = boost::move(p.first);
m_data.second = boost::move(p.second);
const_cast<A&>(m_data.first) = ::boost::move(p.first);
m_data.second = ::boost::move(p.second);
}
template<class V>
void do_move(V &v)
{ m_data = boost::move(v); }
void do_move_assign(V &v)
{ m_data = ::boost::move(v); }
};
}//namespace container_detail {
@@ -282,7 +249,7 @@ class rbtree
//First recycle a node (this can't throw)
try{
//This can throw
*p = other;
p->do_assign(other.m_data);
return p;
}
catch(...){
@@ -295,7 +262,7 @@ class rbtree
}
}
else{
return m_holder.create_node(other);
return m_holder.create_node(other.m_data);
}
}
@@ -319,7 +286,7 @@ class rbtree
//First recycle a node (this can't throw)
try{
//This can throw
*p = boost::move(other);
p->do_move_assign(const_cast<Node &>(other).m_data);
return p;
}
catch(...){
@@ -332,7 +299,7 @@ class rbtree
}
}
else{
return m_holder.create_node(other);
return m_holder.create_node(other.m_data);
}
}
@@ -478,8 +445,10 @@ class rbtree
iterator(){}
//Pointer like operators
reference operator*() const { return this->m_it->get_data(); }
pointer operator->() const { return pointer(&this->m_it->get_data()); }
reference operator*() const
{ return this->m_it->get_data(); }
pointer operator->() const
{ return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data()); }
//Increment / Decrement
iterator& operator++()
@@ -532,9 +501,28 @@ class rbtree
}
rbtree(BOOST_RV_REF(rbtree) x)
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
: AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
{}
rbtree(const rbtree& x, const allocator_type &a)
: AllocHolder(a, x.key_comp())
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
: AllocHolder(a, x.key_comp())
{
if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont());
}
else{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
}
~rbtree()
{} //AllocHolder clears the tree
@@ -552,7 +540,7 @@ class rbtree
//Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed
//automatically
Icont other_tree(boost::move(this->icont()));
Icont other_tree(::boost::move(this->icont()));
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
@@ -578,7 +566,7 @@ class rbtree
if(this_alloc == x_alloc){
//Destroy and swap pointers
this->clear();
this->icont() = boost::move(x.icont());
this->icont() = ::boost::move(x.icont());
//Move allocator if needed
this->AllocHolder::move_assign_alloc(x);
}
@@ -587,7 +575,7 @@ class rbtree
//Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed
//automatically
Icont other_tree(boost::move(this->icont()));
Icont other_tree(::boost::move(this->icont()));
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
@@ -872,9 +860,9 @@ class rbtree
if(this->empty()){
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
const_iterator end(this->end());
const_iterator hint(this->cend());
for( ; first != last; ++first)
this->insert_unique(end, *first);
hint = this->insert_unique(hint, *first);
}
else{
for( ; first != last; ++first)
@@ -913,9 +901,9 @@ class rbtree
{
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
const_iterator end(this->cend());
const_iterator hint(this->cend());
for( ; first != last; ++first)
this->insert_equal(end, *first);
hint = this->insert_equal(hint, *first);
}
iterator erase(const_iterator position)

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000.
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,13 @@ namespace container_detail {
struct nat{};
template <typename U>
struct LowPriorityConversion
{
// Convertible from T with user-defined-conversion rank.
LowPriorityConversion(const U&) { }
};
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -21,13 +21,23 @@
#include <boost/move/move.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <algorithm>
namespace boost {
namespace container {
namespace container_detail {
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>(
static_cast<void*>(
const_cast<char*>(
&reinterpret_cast<const char&>(obj)
)));
}
template<class T>
const T &max_value(const T &a, const T &b)
{ return a > b ? a : b; }
@@ -262,6 +272,7 @@ F uninitialized_copy_or_move_alloc
return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
}
} //namespace container {
} //namespace boost {

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011.
// (C) Copyright Ion Gaztanaga 2005-2012.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -26,6 +26,11 @@
#define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
#endif
#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
#endif
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -26,7 +26,7 @@
#include <boost/container/detail/flat_tree.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/move/move.hpp>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -165,8 +165,13 @@ class flat_map
get_flat_tree_iterators
<pointer>::const_reverse_iterator const_reverse_iterator;
typedef A allocator_type;
//!Standard extension
typedef A stored_allocator_type;
//!Standard extension for C++03 compilers with non-movable std::pair
typedef impl_value_type movable_value_type;
public:
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
@@ -209,23 +214,38 @@ class flat_map
//! <b>Effects</b>: Copy constructs a flat_map.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_map(const flat_map<Key,T,Pred,A>& x)
flat_map(const flat_map& x)
: m_flat_tree(x.m_flat_tree) {}
//! <b>Effects</b>: Move constructs a flat_map.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_map(BOOST_RV_REF(flat_map) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{}
//! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_map(const flat_map& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
{}
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
: m_flat_tree(boost::move(x.m_flat_tree), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_map<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: Move constructs a flat_map.
@@ -234,7 +254,7 @@ class flat_map
//! <b>Complexity</b>: Construct.
//!
//! <b>Postcondition</b>: x is emptied.
flat_map<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_map) mx)
flat_map& operator=(BOOST_RV_REF(flat_map) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
@@ -484,7 +504,7 @@ class flat_map
//! to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(BOOST_RV_REF(impl_value_type) x)
std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
{
return container_detail::force<std::pair<iterator,bool> >
(m_flat_tree.insert_unique(boost::move(x)));
@@ -515,8 +535,11 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
{ return container_detail::force_copy<iterator>
(m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(container_detail::force<impl_value_type>(x)))); }
{
return container_detail::force_copy<iterator>
(m_flat_tree.insert_unique( container_detail::force<impl_const_iterator>(position)
, boost::move(container_detail::force<impl_value_type>(x))));
}
//! <b>Effects</b>: Inserts an element move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -527,7 +550,7 @@ class flat_map
//! right before p) plus insertion linear to the elements with bigger keys than x.
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
{
return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(x)));
@@ -704,13 +727,13 @@ class flat_map
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
{ return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
{ return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -916,6 +939,8 @@ class flat_multimap
typedef A allocator_type;
//Non-standard extension
typedef A stored_allocator_type;
//!Standard extension for C++03 compilers with non-movable std::pair
typedef impl_value_type movable_value_type;
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
@@ -960,28 +985,43 @@ class flat_multimap
//! <b>Effects</b>: Copy constructs a flat_multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multimap(const flat_multimap<Key,T,Pred,A>& x)
flat_multimap(const flat_multimap& x)
: m_flat_tree(x.m_flat_tree) { }
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_multimap(BOOST_RV_REF(flat_multimap) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{ }
//! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multimap(const flat_multimap& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
{}
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
: m_flat_tree(boost::move(x.m_flat_tree), a)
{ }
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multimap<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: this->swap(x.get()).
//!
//! <b>Complexity</b>: Constant.
flat_multimap<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_multimap) mx)
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
@@ -1359,14 +1399,14 @@ class flat_multimap
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator>
equal_range(const key_type& x) const
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -100,14 +100,14 @@ class flat_set
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
//! <b>Effects</b>: Defatuls constructs an empty flat_map.
//! <b>Effects</b>: Default constructs an empty flat_set.
//!
//! <b>Complexity</b>: Constant.
explicit flat_set()
: m_flat_tree()
{}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
//! <b>Effects</b>: Constructs an empty flat_set using the specified
//! comparison object and allocator.
//!
//! <b>Complexity</b>: Constant.
@@ -116,7 +116,7 @@ class flat_set
: m_flat_tree(comp, a)
{}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
//! allocator, and inserts elements from the range [first ,last ).
//!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
@@ -143,31 +143,47 @@ class flat_set
: m_flat_tree(ordered_range, first, last, comp, a)
{}
//! <b>Effects</b>: Copy constructs a map.
//! <b>Effects</b>: Copy constructs a set.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_set(const flat_set<T,Pred,A>& x)
: m_flat_tree(x.m_flat_tree) {}
flat_set(const flat_set& x)
: m_flat_tree(x.m_flat_tree)
{}
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
//! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_set(BOOST_RV_REF(flat_set) mx)
: m_flat_tree(boost::move(mx.m_flat_tree))
{}
//! <b>Effects</b>: Makes *this a copy of x.
//! <b>Effects</b>: Copy constructs a set using the specified allocator.
//!
//! <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; }
flat_set(const flat_set& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
{}
//! <b>Effects</b>: Move constructs a set using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a)
: m_flat_tree(boost::move(mx.m_flat_tree), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_set<T,Pred,A>& operator=(BOOST_RV_REF(flat_set) mx)
flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: Makes *this a copy of the previous value of xx.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_set& operator=(BOOST_RV_REF(flat_set) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out
@@ -729,7 +745,7 @@ class flat_multiset
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
//! <b>Effects</b>: Defatuls constructs an empty flat_map.
//! <b>Effects</b>: Default constructs an empty flat_multiset.
//!
//! <b>Complexity</b>: Constant.
explicit flat_multiset()
@@ -761,17 +777,47 @@ class flat_multiset
: 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))
//! <b>Effects</b>: Copy constructs a flat_multiset.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multiset(const flat_multiset& x)
: m_flat_tree(x.m_flat_tree)
{}
flat_multiset<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
//! <b>Effects</b>: Move constructs a flat_multiset. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
flat_multiset(BOOST_RV_REF(flat_multiset) mx)
: m_flat_tree(boost::move(mx.m_flat_tree))
{}
//! <b>Effects</b>: Copy constructs a flat_multiset using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multiset(const flat_multiset& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
{}
//! <b>Effects</b>: Move constructs a flat_multiset using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a)
: m_flat_tree(boost::move(mx.m_flat_tree), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
{ m_flat_tree = x.m_flat_tree; return *this; }
flat_multiset<T,Pred,A>& operator=(BOOST_RV_REF(flat_multiset) mx)
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -65,30 +65,7 @@ template <class T, class VoidPointer>
struct list_node
: public list_hook<VoidPointer>::type
{
list_node()
: m_data()
{}
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<class ...Args>
list_node(Args &&...args)
: m_data(boost::forward<Args>(args)...)
{}
#else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
list_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
typedef typename list_hook<VoidPointer>::type hook_type;
T m_data;
};
@@ -374,6 +351,34 @@ class list
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
{}
//! <b>Effects</b>: Copy constructs a list using the specified allocator.
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
list(const list& x, const allocator_type &a)
: AllocHolder(a)
{ this->insert(this->cbegin(), x.begin(), x.end()); }
//! <b>Effects</b>: Move constructor sing the specified allocator.
//! Moves mx's resources to *this.
//!
//! <b>Throws</b>: If allocation or value_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
list(BOOST_RV_REF(list) x, const allocator_type &a)
: AllocHolder(a)
{
if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont());
}
else{
this->insert(this->cbegin(), x.begin(), x.end());
}
}
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the list.
//!

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -158,7 +158,7 @@ class map
: m_tree(first, last, comp, a, true)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
@@ -175,29 +175,52 @@ class map
: m_tree(ordered_range, first, last, comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a map.
//!
//! <b>Complexity</b>: Linear in x.size().
map(const map<Key,T,Pred,A>& x)
map(const map& x)
: m_tree(x.m_tree)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
map(BOOST_RV_REF(map) x)
: m_tree(boost::move(x.m_tree))
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a map using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
map(const map& x, const allocator_type &a)
: m_tree(x.m_tree, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Move constructs a map using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise.
//!
//! <b>Postcondition</b>: x is emptied.
map(BOOST_RV_REF(map) x, const allocator_type &a)
: m_tree(boost::move(x.m_tree), a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -833,7 +856,7 @@ class multimap
: m_tree(comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
@@ -848,7 +871,7 @@ class multimap
: m_tree(first, last, comp, a, false)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
@@ -864,27 +887,48 @@ class multimap
: m_tree(ordered_range, first, last, comp, a)
{}
//! <b>Effects</b>: Copy constructs a multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
multimap(const multimap<Key,T,Pred,A>& x)
multimap(const multimap& x)
: m_tree(x.m_tree)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
multimap(BOOST_RV_REF(multimap) x)
: m_tree(boost::move(x.m_tree))
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a multimap.
//!
//! <b>Complexity</b>: Linear in x.size().
multimap(const multimap& x, const allocator_type &a)
: m_tree(x.m_tree, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Move constructs a multimap using the specified allocator.
//! Constructs *this using x's resources.
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
//!
//! <b>Postcondition</b>: x is emptied.
multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
: m_tree(boost::move(x.m_tree), a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Makes *this a copy of x.

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -144,16 +144,31 @@ class set
//! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
set(BOOST_RV_REF(set) x)
: m_tree(boost::move(x.m_tree))
{}
//! <b>Effects</b>: Makes *this a copy of x.
//! <b>Effects</b>: Copy constructs a set using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
set(const set& x, const allocator_type &a)
: m_tree(x.m_tree, a)
{}
//! <b>Effects</b>: Move constructs a set using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
set(BOOST_RV_REF(set) x, const allocator_type &a)
: m_tree(boost::move(x.m_tree), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().
set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
{ m_tree = x.m_tree; return *this; }
@@ -716,13 +731,30 @@ class multiset
//! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Construct.
//! <b>Complexity</b>: Constant.
//!
//! <b>Postcondition</b>: x is emptied.
multiset(BOOST_RV_REF(multiset) x)
: m_tree(boost::move(x.m_tree))
{}
//! <b>Effects</b>: Copy constructs a multiset using the specified allocator.
//!
//! <b>Complexity</b>: Linear in x.size().
multiset(const multiset& x, const allocator_type &a)
: m_tree(x.m_tree, a)
{}
//! <b>Effects</b>: Move constructs a multiset using the specified allocator.
//! Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
//!
//! <b>Postcondition</b>: x is emptied.
multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
: m_tree(boost::move(x.m_tree), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
//!
//! <b>Complexity</b>: Linear in x.size().

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -65,31 +65,7 @@ template <class T, class VoidPointer>
struct slist_node
: public slist_hook<VoidPointer>::type
{
slist_node()
: m_data()
{}
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<class ...Args>
slist_node(Args &&...args)
: m_data(boost::forward<Args>(args)...)
{}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
typedef typename slist_hook<VoidPointer>::type hook_type;
T m_data;
};
@@ -391,6 +367,34 @@ class slist
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
{}
//! <b>Effects</b>: Copy constructs a list using the specified allocator.
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
slist(const slist& x, const allocator_type &a)
: AllocHolder(a)
{ this->insert_after(this->before_begin(), x.begin(), x.end()); }
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocation or value_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
slist(BOOST_RV_REF(slist) x, const allocator_type &a)
: AllocHolder(a)
{
if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont());
}
else{
this->insert(this->cbegin(), x.begin(), x.end());
}
}
//! <b>Effects</b>: Makes *this contain the same elements as x.
//!
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -34,7 +34,7 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <algorithm>
@@ -78,10 +78,6 @@ struct smart_ptr_type<T*>
{ return ptr;}
};
template<class Ptr>
inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
{ return smart_ptr_type<Ptr>::get(ptr); }
template <class C>
class clear_on_destroy
{
@@ -110,13 +106,10 @@ class clear_on_destroy
template<class VoidPtr>
struct node_type_base
{/*
node_type_base(VoidPtr p)
: up(p)
{}*/
{
node_type_base()
{}
void set_pointer(VoidPtr p)
void set_pointer(const VoidPtr &p)
{ up = p; }
VoidPtr up;
@@ -126,33 +119,6 @@ template<typename VoidPointer, typename T>
struct node_type
: public node_type_base<VoidPointer>
{
node_type()
: value()
{}
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<class ...Args>
node_type(Args &&...args)
: value(boost::forward<Args>(args)...)
{}
#else //BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif//BOOST_CONTAINER_PERFECT_FORWARDING
void set_pointer(VoidPointer p)
{ node_type_base<VoidPointer>::set_pointer(p); }
T value;
};
@@ -206,17 +172,17 @@ class iterator
private:
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
}
static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
{
return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
return const_node_type_ptr_t(static_cast<const node_type_t*>(container_detail::to_raw_pointer(p)));
}
static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
{
return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
return void_ptr_ptr(static_cast<void_ptr*>(container_detail::to_raw_pointer(p)));
}
reference dereference() const
@@ -353,35 +319,37 @@ BOOST_JOIN(check_invariant_,__LINE__).touch();
/// @endcond
//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
//!drop-in replacement implemented as a node container, offering iterator and reference
//!stability.
//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
//! drop-in replacement implemented as a node container, offering iterator and reference
//! stability.
//!
//!More details taken the author's blog: (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" > Introducing stable_vector</a>)
//! More details taken the author's blog:
//! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
//! Introducing stable_vector</a>)
//!
//!We present stable_vector, a fully STL-compliant stable container that provides
//!most of the features of std::vector except element contiguity.
//! We present stable_vector, a fully STL-compliant stable container that provides
//! most of the features of std::vector except element contiguity.
//!
//!General properties: stable_vector satisfies all the requirements of a container,
//!a reversible container and a sequence and provides all the optional operations
//!present in std::vector. Like std::vector, iterators are random access.
//!stable_vector does not provide element contiguity; in exchange for this absence,
//!the container is stable, i.e. references and iterators to an element of a stable_vector
//!remain valid as long as the element is not erased, and an iterator that has been
//!assigned the return value of end() always remain valid until the destruction of
//!the associated stable_vector.
//! General properties: stable_vector satisfies all the requirements of a container,
//! a reversible container and a sequence and provides all the optional operations
//! present in std::vector. Like std::vector, iterators are random access.
//! stable_vector does not provide element contiguity; in exchange for this absence,
//! the container is stable, i.e. references and iterators to an element of a stable_vector
//! remain valid as long as the element is not erased, and an iterator that has been
//! assigned the return value of end() always remain valid until the destruction of
//! the associated stable_vector.
//!
//!Operation complexity: The big-O complexities of stable_vector operations match
//!exactly those of std::vector. In general, insertion/deletion is constant time at
//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
//!does not internally perform any value_type destruction, copy or assignment
//!operations other than those exactly corresponding to the insertion of new
//!elements or deletion of stored elements, which can sometimes compensate in terms
//!of performance for the extra burden of doing more pointer manipulation and an
//!additional allocation per element.
//! Operation complexity: The big-O complexities of stable_vector operations match
//! exactly those of std::vector. In general, insertion/deletion is constant time at
//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
//! does not internally perform any value_type destruction, copy or assignment
//! operations other than those exactly corresponding to the insertion of new
//! elements or deletion of stored elements, which can sometimes compensate in terms
//! of performance for the extra burden of doing more pointer manipulation and an
//! additional allocation per element.
//!
//!Exception safety: As stable_vector does not internally copy elements around, some
//!operations provide stronger exception safety guarantees than in std::vector:
//! Exception safety: As stable_vector does not internally copy elements around, some
//! operations provide stronger exception safety guarantees than in std::vector:
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> >
#else
@@ -524,7 +492,7 @@ class stable_vector
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
explicit stable_vector(const A& al)
explicit stable_vector(const allocator_type& al)
: internal_data(al),impl(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
@@ -538,7 +506,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to n.
explicit stable_vector(size_type n)
: internal_data(A()),impl(A())
: internal_data(),impl()
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n);
@@ -553,7 +521,7 @@ class stable_vector
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
stable_vector(size_type n, const T& t, const A& al=A())
stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
: internal_data(al),impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -570,7 +538,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InputIterator>
stable_vector(InputIterator first,InputIterator last,const A& al=A())
stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
: internal_data(al),impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -607,6 +575,40 @@ class stable_vector
this->priv_swap_members(x);
}
//! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
stable_vector(const stable_vector& x, const allocator_type &a)
: internal_data(a), impl(a)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cbegin(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves mx's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
: internal_data(a), impl(a)
{
if(this->node_alloc() == x.node_alloc()){
this->priv_swap_members(x);
}
else{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cbegin(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
}
//! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
//! and used memory is deallocated.
//!
@@ -709,7 +711,7 @@ class stable_vector
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator()const {return node_alloc();}
allocator_type get_allocator()const {return this->node_alloc();}
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -1137,7 +1139,7 @@ class stable_vector
void emplace_back(Args &&...args)
{
typedef emplace_functor<Args...> EmplaceFunctor;
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
}
@@ -1157,7 +1159,7 @@ class stable_vector
//Just call more general insert(pos, size, value) and return iterator
size_type pos_n = position - cbegin();
typedef emplace_functor<Args...> EmplaceFunctor;
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
return iterator(this->begin() + pos_n);
@@ -1172,7 +1174,7 @@ class stable_vector
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
@@ -1186,7 +1188,7 @@ class stable_vector
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
@@ -1482,12 +1484,12 @@ class stable_vector
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
}
static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
{
return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
return node_type_base_ptr_t(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p)));
}
static value_type& value(const void_ptr &p)
@@ -1529,7 +1531,9 @@ class stable_vector
{
node_type_ptr_t p = this->allocate_one();
try{
boost::container::construct_in_place(this->node_alloc(), &*p, it);
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), it);
//This does not throw
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(up);
}
catch(...){
@@ -1621,7 +1625,9 @@ class stable_vector
p = mem.front();
mem.pop_front();
//This can throw
boost::container::construct_in_place(this->node_alloc(), &*p, first);
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
//This does not throw
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(void_ptr_ptr(&it[i]));
++first;
it[i] = p;
@@ -1650,7 +1656,9 @@ class stable_vector
break;
}
//This can throw
boost::container::construct_in_place(this->node_alloc(), &*p, first);
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
//This does not throw
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(void_ptr_ptr(&it[i]));
++first;
it[i]=p;

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -43,7 +43,7 @@
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp>
#include <boost/static_assert.hpp>
@@ -620,12 +620,12 @@ class basic_string
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
//! <b>Throws</b>: If allocator_type's default constructor throws.
basic_string(const basic_string& s)
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
{ this->priv_range_initialize(s.begin(), s.end()); }
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
//! <b>Effects</b>: Move constructor. Moves s's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
@@ -634,6 +634,32 @@ class basic_string
: base_t(boost::move((base_t&)s))
{}
//! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Throws</b>: If allocation throws.
basic_string(const basic_string& s, const allocator_type &a)
: base_t(a)
{ this->priv_range_initialize(s.begin(), s.end()); }
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves s's resources to *this.
//!
//! <b>Throws</b>: If allocation throws.
//!
//! <b>Complexity</b>: Constant if a == s.get_allocator(), linear otherwise.
basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
: base_t(a)
{
if(a == this->alloc()){
this->swap_data(s);
}
else{
this->priv_range_initialize(s.begin(), s.end());
}
}
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by a specific number of characters of the s string.
basic_string(const basic_string& s, size_type pos, size_type n = npos,

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -38,7 +38,7 @@
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/move/move.hpp>
#include <boost/move/move_helpers.hpp>
@@ -46,6 +46,7 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/advanced_insert_int.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace container {
@@ -540,6 +541,40 @@ class vector : private container_detail::vector_alloc_holder<A>
: base_t(boost::move(mx.alloc()))
{ this->swap_members(mx); }
//! <b>Effects</b>: Copy constructs a vector using the specified allocator.
//!
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Throws</b>: If allocation
//! throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
vector(const vector &x, const allocator_type &a)
: base_t(a)
{
this->assign( container_detail::to_raw_pointer(x.members_.m_start)
, container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
}
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves mx's resources to *this if a == allocator_type().
//! Otherwise copies values from x to *this.
//!
//! <b>Throws</b>: If allocation or T's copy constructor throws.
//!
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
vector(BOOST_RV_REF(vector) mx, const allocator_type &a)
: base_t(a)
{
if(mx.alloc() == a){
this->swap_members(mx);
}
else{
this->assign( container_detail::to_raw_pointer(mx.members_.m_start)
, container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size));
}
}
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the vector.
//!
@@ -1428,6 +1463,146 @@ class vector : private container_detail::vector_alloc_holder<A>
}
}
public:
//Absolutely experimental. This function might change, disappear or simply crash!
template<class BiDirPosIt, class BiDirValueIt>
void insert_ordered_at(size_type element_count, BiDirPosIt last_position_it, BiDirValueIt last_value_it)
{
const size_type old_size_pos = this->size();
this->reserve(old_size_pos + element_count);
T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
size_type insertions_left = element_count;
size_type next_pos = old_size_pos;
size_type hole_size = element_count;
//Exception rollback. If any copy throws before the hole is filled, values
//already inserted/copied at the end of the buffer will be destroyed.
typename value_traits::ArrayDestructor past_hole_values_destroyer
(begin_ptr + old_size_pos + element_count, this->alloc(), size_type(0u));
//Loop for each insertion backwards, first moving the elements after the insertion point,
//then inserting the element.
while(insertions_left){
const size_type pos = static_cast<size_type>(*(--last_position_it));
BOOST_ASSERT(pos <= old_size_pos);
//Shift the range after the insertion point, function will take care if the shift
//crosses the size() boundary, using copy/move or uninitialized copy/move if necessary.
size_type new_hole_size = insert_ordered_at_shift_range(pos, next_pos, this->size(), insertions_left);
if(new_hole_size > 0){
//The hole was reduced by insert_ordered_at_shift_range so expand exception rollback range backwards
past_hole_values_destroyer.increment_size_backwards(next_pos - pos);
//Insert the new value in the hole
allocator_traits_type::construct(this->alloc(), begin_ptr + pos + insertions_left - 1, *(--last_value_it));
--new_hole_size;
if(new_hole_size == 0){
//Hole was just filled, disable exception rollback and change vector size
past_hole_values_destroyer.release();
this->members_.m_size += element_count;
}
else{
//The hole was reduced by the new insertion by one
past_hole_values_destroyer.increment_size_backwards(size_type(1u));
}
}
else{
if(hole_size){
//Hole was just filled by insert_ordered_at_shift_range, disable exception rollback and change vector size
past_hole_values_destroyer.release();
this->members_.m_size += element_count;
}
//Insert the new value in the already constructed range
begin_ptr[pos + insertions_left - 1] = *(--last_value_it);
}
--insertions_left;
hole_size = new_hole_size;
next_pos = pos;
}
}
//Takes the range pointed by [first_pos, last_pos) and shifts it to the right
//by 'shift_count'. 'limit_pos' marks the end of constructed elements.
//
//Precondition: first_pos <= last_pos <= limit_pos
//
//The shift operation might cross limit_pos so elements to moved beyond limit_pos
//are uninitialized_moved with an allocator. Other elements are moved.
//
//The shift operation might left uninitialized elements after limit_pos
//and the number of uninitialized elements is returned by the function.
//
//Old situation:
// first_pos last_pos old_limit
// | | |
// ____________V_______V__________________V_____________
//| prefix | range | suffix |raw_mem ~
//|____________|_______|__________________|_____________~
//
//New situation in Case A (hole_size == 0):
// range is moved through move assignments
//
// first_pos last_pos old_limit
// | | |
// ____________V_______V__________________V_____________
//| prefix' | | | range |suffix'|raw_mem ~
//|________________+______|___^___|_______|_____________~
// | |
// |_>_>_>_>_>^
//
//
//New situation in Case B (hole_size >= 0):
// range is moved through uninitialized moves
//
// first_pos last_pos old_limit
// | | |
// ____________V_______V__________________V________________
//| prefix' | | | [hole] | range |
//|_______________________________________|________|___^___|
// | |
// |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^
//
//New situation in Case C (hole_size == 0):
// range is moved through move assignments and uninitialized moves
//
// first_pos last_pos old_limit
// | | |
// ____________V_______V__________________V___
//| prefix' | | | range |
//|___________________________________|___^___|
// | |
// |_>_>_>_>_>_>_>_>_>_>_>^
size_type insert_ordered_at_shift_range(size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count)
{
BOOST_ASSERT(first_pos <= last_pos);
BOOST_ASSERT(last_pos <= limit_pos);
//
T* const begin_ptr = container_detail::to_raw_pointer(this->members_.m_start);
size_type hole_size = 0;
//Case A:
if((last_pos + shift_count) <= limit_pos){
//All move assigned
boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count);
}
//Case B:
else if((first_pos + shift_count) >= limit_pos){
//All uninitialized_moved
::boost::container::uninitialized_move_alloc
(this->alloc(), begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + first_pos + shift_count);
hole_size = last_pos + shift_count - limit_pos;
}
//Case C:
else{
//Some uninitialized_moved
T* const limit_ptr = begin_ptr + limit_pos;
T* const boundary_ptr = limit_ptr - shift_count;
::boost::container::uninitialized_move_alloc
(this->alloc(), boundary_ptr, begin_ptr + last_pos, limit_ptr);
//The rest is move assigned
boost::move_backward(begin_ptr + first_pos, boundary_ptr, limit_ptr + shift_count);
}
return hole_size;
}
private:
void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
{
//n can't be 0, because there is nothing to do in that case

View File

@@ -1,5 +1,5 @@
<!--
Copyright 2005-2011 Ion Gaztanaga
Copyright 2005-2012 Ion Gaztanaga
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->

View File

@@ -1,10 +1,10 @@
->Change "insert" and "push_back"/"push_front" to catch non-const rvalues
->Add an example with stateful allocators
->Add test to check convertible types in push_back/insert
->Add SCARY iterators.
Review allocator traits
-> Explicit instantiation of simple allocator & std::allocator to detect missing allocator_traits calls
-> Avoid any rebind<>::other
-> Review select_on_container_copy_xxx
-> Review propagate_on_xxx
@@ -12,13 +12,13 @@ Review allocator traits
-> Default + swap move constructors correct?
-> Review container documentation in swap/copy/move regarding allocators
Check all move constructors: swap might not be a valid idiom, allocators must be move constructed, intrusive containers are now movable
Check all move constructors: swap might not be a valid idiom, allocators must be move constructed,
intrusive containers are now movable
Add and test:
Test different propagation values and with inequal allocators
propagate_on_container_move_assignment
select_on_container_copy_construction
propagate_on_container_swap
@@ -28,19 +28,12 @@ Test move constructors with data values and unequal allocators
An allocator should use a smart allocator not constructible from raw pointers to catch missing pointer_traits calls
Review all internal container swap's to check allocator propagation is correct
Add initializer lists
Write forward_list
Review all move constructors to test if allocator is move constructed
check move if noexcept conditions in vector, deque and stable_vector
Add new allocator propagation copy constructors
Detect always equal or unequal allocators at compiler time. operator== returns true_type or false_type
Review all destructors (search for "~") to detect placement destruction and replace it with allocator_traits::destroy
All functions from base classes like vector_base, node_alloc_holder, etc., should be named with underscore or
similar to avoid namespace pollution.
change virtual functions with pointers to avoid template instantiation for every type

View File

@@ -43,6 +43,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_test.vcpr
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_adaptor_test", "scoped_allocator_adaptor.vcproj", "{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scoped_allocator_usage_test", "scoped_allocator_usage_test.vcproj", "{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -95,6 +103,14 @@ Global
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.ActiveCfg = Debug|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.ActiveCfg = Debug|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -179,6 +179,9 @@
<Filter
Name="container"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\allocator_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File>
@@ -197,6 +200,9 @@
<File
RelativePath="..\..\..\..\boost\container\map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\scoped_allocator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\set.hpp">
</File>
@@ -215,19 +221,6 @@
<File
RelativePath="..\..\..\..\boost\container\vector.hpp">
</File>
<Filter
Name="allocator"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\allocator\allocator_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\allocator\scoped_allocator.hpp">
</File>
</Filter>
<Filter
Name="detail"
Filter="">
@@ -264,6 +257,9 @@
<File
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File>

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="scoped_allocator_adaptor_test"
ProjectGUID="{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/scoped_allocator_adaptor_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/scoped_allocator_adaptor_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/scoped_allocator_adaptor_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/scoped_allocator_adaptor_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/scoped_allocator_adaptor_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\scoped_allocator_adaptor_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="scoped_allocator_usage_test"
ProjectGUID="{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/scoped_allocator_usage_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/scoped_allocator_usage_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/scoped_allocator_usage_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/scoped_allocator_usage_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/scoped_allocator_usage_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\scoped_allocator_usage_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -9,7 +9,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <cstddef>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/integral_constant.hpp>

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -112,10 +112,10 @@ class dummy_test_allocator
{}
pointer address(reference value)
{ return pointer(addressof(value)); }
{ return pointer(container_detail::addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
{ return const_pointer(container_detail::addressof(value)); }
pointer allocate(size_type, cvoid_ptr = 0)
{ return 0; }

View File

@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -86,10 +86,10 @@ class expand_bwd_test_allocator
, m_offset(other.m_offset), m_allocations(0){ }
pointer address(reference value)
{ return pointer(addressof(value)); }
{ return pointer(container_detail::addressof(value)); }
const_pointer address(const_reference value) const
{ return const_pointer(addressof(value)); }
{ return const_pointer(container_detail::addressof(value)); }
pointer allocate(size_type , cvoid_ptr hint = 0)
{ (void)hint; return 0; }

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -228,17 +228,17 @@ class recursive_flat_multiset
{
public:
recursive_flat_multiset(const recursive_flat_multiset &c)
: id_(c.id_), flat_set_(c.flat_set_)
: id_(c.id_), flat_multiset_(c.flat_multiset_)
{}
recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
{
id_ = c.id_;
flat_set_= c.flat_set_;
flat_multiset_= c.flat_multiset_;
return *this;
}
int id_;
flat_multiset<recursive_flat_multiset> flat_set_;
flat_multiset<recursive_flat_multiset> flat_multiset_;
friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
{ return a.id_ < b.id_; }
};

View File

@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -387,10 +387,17 @@ int map_test ()
return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1;
{
IntType i1(i);
IntType i2(i);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
{ //Check equal_range
std::pair<typename MyBoostMultiMap::iterator, typename MyBoostMultiMap::iterator> bret =
boostmultimap->equal_range(boostmultimap->begin()->first);
std::pair<typename MyStdMultiMap::iterator, typename MyStdMultiMap::iterator> sret =
stdmultimap->equal_range(stdmultimap->begin()->first);
if( std::distance(bret.first, bret.second) !=
std::distance(sret.first, sret.second) ){
return 1;
}
}
{
IntType i1(i);

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
#include <memory>
#include <string>
#include <boost/move/move.hpp>
#include <boost/container/map.hpp>
#include <boost/container/scoped_allocator.hpp>
template <typename Ty>
class SimpleAllocator
{
public:
typedef Ty value_type;
typedef typename std::allocator<Ty>::pointer pointer;
typedef typename std::allocator<Ty>::size_type size_type;
SimpleAllocator(int value)
: _value(value)
{}
template <typename T>
SimpleAllocator(const SimpleAllocator<T> &other)
: _value(other._value)
{}
pointer allocate(size_type n)
{
return _allocator.allocate(n);
}
void deallocate(pointer p, size_type n)
{
_allocator.deallocate(p, n);
}
private:
int _value;
std::allocator<Ty> _allocator;
template <typename T> friend class SimpleAllocator;
};
template <typename Ty>
class ScopedAllocator : public boost::container::scoped_allocator_adaptor<SimpleAllocator<Ty> >
{
private:
typedef boost::container::scoped_allocator_adaptor<SimpleAllocator<Ty> > Base;
public:
ScopedAllocator(int value)
: Base(SimpleAllocator<Ty>(value))
{}
};
class Resource
{
private: // Not copyable
Resource(const Resource &);
Resource &operator=(const Resource &);
public:
typedef SimpleAllocator<int> allocator_type;
Resource(BOOST_RV_REF(Resource)other)
: _value(other._value), _allocator(boost::move(other._allocator))
{
other._value = -1;
}
Resource(BOOST_RV_REF(Resource)other, const allocator_type &allocator)
: _value(other._value), _allocator(allocator)
{
other._value = -1;
}
Resource(int value, const allocator_type &allocator)
: _value(value), _allocator(allocator)
{}
private:
int _value;
allocator_type _allocator;
};
typedef std::pair<const std::string, Resource> MapNode;
typedef boost::container::scoped_allocator_adaptor<SimpleAllocator<MapNode> > MapAllocator;
typedef boost::container::map<std::string, Resource, std::less<std::string>, MapAllocator> Map;
int main()
{
Map map1(std::less<std::string>(), SimpleAllocator<MapNode>(5));
map1.emplace("foo", 42);
map1.emplace("bar", 11);
//Map map2 = map1;
return 0;
}

View File

@@ -1,6 +1,6 @@
////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -201,8 +201,10 @@ void test_move()
{
//Now test move semantics
C original;
original.emplace();
C move_ctor(boost::move(original));
C move_assign;
move_assign.emplace();
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -95,6 +95,26 @@ enum Test
int main()
{
{
const std::size_t positions_length = 10;
std::size_t positions[positions_length];
vector<int> vector_int;
vector<int> vector_int2(positions_length);
for(std::size_t i = 0; i != positions_length; ++i){
positions[i] = 0u;
}
for(std::size_t i = 0, max = vector_int2.size(); i != max; ++i){
vector_int2[i] = i;
}
vector_int.insert(vector_int.begin(), 999);
vector_int.insert_ordered_at(positions_length, positions + positions_length, vector_int2.end());
for(std::size_t i = 0, max = vector_int.size(); i != max; ++i){
std::cout << vector_int[i] << std::endl;
}
}
recursive_vector_test();
{
//Now test move semantics
@@ -134,7 +154,8 @@ int main()
if(!boost::container::test::test_propagate_allocator<vector>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//