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 --------------------------------- # 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 # distribution is subject to the Boost Software License, Version
# 1.0. (See accompanying file LICENSE_1_0.txt or copy at # 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt) # http://www.boost.org/LICENSE_1_0.txt)
@@ -27,6 +27,8 @@ doxygen autodoc
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\ <doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\ \"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_RV_REF(T)=T &&\" \\ \"BOOST_RV_REF(T)=T &&\" \\
\"BOOST_RV_REF_BEG=\" \\
\"BOOST_RV_REF_END=&&\" \\
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\ \"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
\"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T<a, b> &&\" \\ \"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> &&\" \\ \"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 / Distributed under the 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 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,7 +8,7 @@
[library Boost.Container [library Boost.Container
[quickbook 1.5] [quickbook 1.5]
[authors [Gaztanaga, Ion]] [authors [Gaztanaga, Ion]]
[copyright 2009-2011 Ion Gaztanaga] [copyright 2009-2012 Ion Gaztanaga]
[id container] [id container]
[dirname container] [dirname container]
[purpose Containers library] [purpose Containers library]
@@ -37,9 +37,9 @@ In short, what does [*Boost.Container] offer?
(they can be safely placed in shared memory). (they can be safely placed in shared memory).
* The library offers new useful containers: * The library offers new useful containers:
* [classref boost::container::flat_map flat_map], * [classref boost::container::flat_map flat_map],
[classref boost::container::flat_map flat_set], [classref boost::container::flat_set flat_set],
[classref boost::container::flat_map flat_multiset] and [classref boost::container::flat_multiset flat_multiset] and
[classref boost::container::flat_map flat_multiset]: drop-in [classref boost::container::flat_multiset flat_multiset]: drop-in
replacements for standard associative containers but more memory friendly and with faster replacements for standard associative containers but more memory friendly and with faster
searches. searches.
* [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid * [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.]] should probably use list instead of slist.]]
[*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement [*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 method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size
with every insertion/erasure, allowing constant-time with every insertion/erasure, allowing constant-time
`splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers `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 by one allocator object could be deallocated by another instance of the same type) and
allocators were not swapped when the container was swapped. allocators were not swapped when the container was swapped.
C++11 further improves stateful allocator support through the C++11 further improves stateful allocator support through
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf [@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`].
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
`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 an allocator writer can customize its behaviour (should the container propagate it in
move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container] 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]. 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] [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] [section:initializer_lists Initializer lists]
[*Boost.Container] does not support initializer lists when constructing or assigning containers [*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 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] [section:release_notes_boost_1_49_00 Boost 1.49 Release]
* Fixed bugs * 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/intrusive/pointer_traits.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/type_traits/integral_constant.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
@@ -53,6 +54,8 @@ struct is_std_allocator< std::allocator<T> >
///@endcond ///@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> template <typename Alloc>
struct allocator_traits struct allocator_traits
{ {
@@ -62,54 +65,54 @@ struct allocator_traits
typedef typename Alloc::value_type value_type; typedef typename Alloc::value_type value_type;
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #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; 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; typedef unspecified const_pointer;
//!Non-standard extension //! Non-standard extension
//!Alloc::reference if such a type exists; otherwise, value_type& //! Alloc::reference if such a type exists; otherwise, value_type&
typedef unspecified pointer; typedef unspecified reference;
//!Non-standard extension //! Non-standard extension
//!Alloc::const_reference if such a type exists ; otherwise, const value_type& //! Alloc::const_reference if such a type exists ; otherwise, const value_type&
typedef unspecified const_pointer; typedef unspecified const_reference;
//!Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>. //! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//! //!
typedef unspecified void_pointer; 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; 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; 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; typedef unspecified size_type;
//!Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant //! 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. //! type with internal constant static member `value` == false.
typedef unspecified propagate_on_container_copy_assignment; typedef unspecified propagate_on_container_copy_assignment;
//!Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant //! 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. //! type with internal constant static member `value` == false.
typedef unspecified propagate_on_container_move_assignment; typedef unspecified propagate_on_container_move_assignment;
//!Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant //! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
//!type with internal constant static member <pre>value</pre> == false. //! type with internal constant static member `value` == false.
typedef unspecified propagate_on_container_swap; typedef unspecified propagate_on_container_swap;
//!Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args> //! 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 //! 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. //! 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 //! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
//!deduced by previously detailed rules. //! deduced by previously detailed rules.
template <class T> using rebind_alloc = unspecified; template <class T> using rebind_alloc = unspecified;
//!In C++03 compilers <pre>rebind_traits</pre> is a struct derived from //! In C++03 compilers `rebind_traits` is a struct derived from
//!<pre>allocator_traits<OtherAlloc><pre>, where `OtherAlloc` is //! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
//!the allocator deduced by rules explained in `rebind_alloc`. //! the allocator deduced by rules explained in `rebind_alloc`.
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >; template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
//!Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. //! 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`. //! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
template <class T> template <class T>
struct portable_rebind_alloc struct portable_rebind_alloc
{ typedef unspecified_type type; }; { typedef unspecified_type type; };
@@ -164,9 +167,9 @@ struct allocator_traits
#if !defined(BOOST_NO_TEMPLATE_ALIASES) #if !defined(BOOST_NO_TEMPLATE_ALIASES)
//C++11 //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> >; 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 //Some workaround for C++03 or C++11 compilers with no template aliases
template <typename T> template <typename T>
struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type 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; typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base;
#if !defined(BOOST_NO_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <typename... Args> template <typename... Args>
rebind_alloc(Args&&... args) rebind_alloc(BOOST_FWD_REF(Args)... args)
: Base(boost::forward<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) \ #define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(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, _)) \ 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) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE() #include BOOST_PP_LOCAL_ITERATE()
#endif //!defined(BOOST_NO_VARIADIC_TEMPLATES) #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
}; };
template <typename T> template <typename T>
struct rebind_traits struct rebind_traits
: allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type> : 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> template <class T>
struct portable_rebind_alloc struct portable_rebind_alloc
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; }; { typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED #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) static pointer allocate(Alloc &a, size_type n)
{ return a.allocate(n); } { return a.allocate(n); }
//!<b>Returns</b>: a.deallocate(p, n) //! <b>Returns</b>: `a.deallocate(p, n)`
//! //!
//!<b>Throws</b>: Nothing //! <b>Throws</b>: Nothing
static void deallocate(Alloc &a, pointer p, size_type n) static void deallocate(Alloc &a, pointer p, size_type n)
{ return a.deallocate(p, n); } { return a.deallocate(p, n); }
//!<b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed; //! <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)...)` //! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
static pointer allocate(Alloc &a, size_type n, const_void_pointer p) static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
{ {
const bool value = boost::container::container_detail:: const bool value = boost::container::container_detail::
@@ -221,8 +224,8 @@ struct allocator_traits
return allocator_traits::priv_allocate(flag, a, n, p); return allocator_traits::priv_allocate(flag, a, n, p);
} }
//!<b>Effects</b>: calls a.destroy(p) if that call is well-formed; //! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
//!otherwise, invokes `p->~T()`. //! otherwise, invokes `p->~T()`.
template<class T> template<class T>
static void destroy(Alloc &a, T*p) static void destroy(Alloc &a, T*p)
{ {
@@ -234,8 +237,8 @@ struct allocator_traits
allocator_traits::priv_destroy(flag, a, p); allocator_traits::priv_destroy(flag, a, p);
} }
//!<b>Returns</b>: a.max_size() if that expression is well-formed; otherwise, //! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise,
//!`numeric_limits<size_type>::max()`. //! `numeric_limits<size_type>::max()`.
static size_type max_size(const Alloc &a) static size_type max_size(const Alloc &a)
{ {
const bool value = boost::container::container_detail:: const bool value = boost::container::container_detail::
@@ -245,8 +248,8 @@ struct allocator_traits
return allocator_traits::priv_max_size(flag, a); return allocator_traits::priv_max_size(flag, a);
} }
//!<b>Returns</b>: a.select_on_container_copy_construction() if that expres sion is well- formed; //! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
//!otherwise, a. //! otherwise, a.
static Alloc select_on_container_copy_construction(const Alloc &a) static Alloc select_on_container_copy_construction(const Alloc &a)
{ {
const bool value = boost::container::container_detail:: 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); return allocator_traits::priv_select_on_container_copy_construction(flag, a);
} }
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!Effects: calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed; //! <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)...)` //! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
template <class T, class ...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; ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...); allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
} }
#endif #endif
///@cond
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
private: private:
static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p) 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) static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
{ return a; } { return a; }
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template<class T, class ...Args> 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:: const bool value = boost::container::container_detail::
has_member_function_callable_with_construct has_member_function_callable_with_construct
@@ -307,19 +310,19 @@ struct allocator_traits
} }
template<class T, class ...Args> 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)...); priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward<Args>(args)...);
} }
template<class T, class ...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)...); } { a.construct( p, ::boost::forward<Args>(args)...); }
template<class T, class ...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)...); } { ::new((void*)p) T(::boost::forward<Args>(args)...); }
#else #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
public: public:
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \ 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) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE() #include BOOST_PP_LOCAL_ITERATE()
#endif //BOOST_CONTAINER_PERFECT_FORWARDING #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
///@endcond ///@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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 //! Type used to tag that the input range is
//! guaranteed to be ordered //! guaranteed to be ordered
struct ordered_range_impl_t {}; struct ordered_range_t
{};
//! Type used to tag that the input range is //! Type used to tag that the input range is
//! guaranteed to be ordered and unique //! guaranteed to be ordered and unique
struct ordered_unique_range_impl_t{}; struct ordered_unique_range_t
: public ordered_range_t
/// @cond {};
typedef ordered_range_impl_t * ordered_range_t;
typedef ordered_unique_range_impl_t *ordered_unique_range_t;
/// @endcond
//! Value used to tag that the input range is //! Value used to tag that the input range is
//! guaranteed to be ordered //! 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 //! Value used to tag that the input range is
//! guaranteed to be ordered and unique //! 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 /// @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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/iterators.hpp>
#include <boost/container/detail/algorithms.hpp> #include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/mpl.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 <boost/container/container_fwd.hpp>
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
@@ -896,6 +896,46 @@ class deque : protected deque_base<T, A>
: Base(boost::move(static_cast<Base&>(x))) : Base(boost::move(static_cast<Base&>(x)))
{ this->swap_members(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 //! <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. //! 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
@@ -17,7 +17,9 @@
#include "config_begin.hpp" #include "config_begin.hpp"
#include <boost/container/detail/workaround.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 <boost/move/move.hpp>
#include <iterator> //std::iterator_traits #include <iterator> //std::iterator_traits
#include <boost/assert.hpp> #include <boost/assert.hpp>
@@ -41,7 +43,6 @@ template<class A, class FwdIt, class Iterator>
struct advanced_insert_aux_proxy struct advanced_insert_aux_proxy
: public advanced_insert_aux_int<Iterator> : 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>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<A>::value_type value_type;
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_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) 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) 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) 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); std::advance(mid, division_count);
if(first_n){ if(first_n){
::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos); ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
first_ = mid; this->first_ = mid;
} }
else{ else{
::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos); ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
last_ = mid; this->last_ = mid;
} }
} }
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n) 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); std::advance(mid, division_count);
if(first_n){ if(first_n){
::boost::copy_or_move(first_, mid, pos); ::boost::copy_or_move(this->first_, mid, pos);
first_ = mid; this->first_ = mid;
} }
else{ else{
::boost::copy_or_move(mid, last_, pos); ::boost::copy_or_move(mid, this->last_, pos);
last_ = mid; this->last_ = mid;
} }
} }
A &a_; A &a_;
@@ -95,7 +96,7 @@ template<class A, class Iterator>
struct default_construct_aux_proxy struct default_construct_aux_proxy
: public advanced_insert_aux_int<Iterator> : 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>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type; typedef typename allocator_traits<A>::value_type value_type;
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_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) virtual void copy_remaining_to(Iterator)
{ //This should never be called with any count { //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) 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) 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; new_count = division_count;
} }
else{ else{
BOOST_ASSERT(difference_type(count_)>= division_count); BOOST_ASSERT(difference_type(this->count_)>= division_count);
new_count = count_ - division_count; new_count = this->count_ - division_count;
} }
this->priv_uninitialized_copy(pos, new_count); this->priv_uninitialized_copy(pos, new_count);
} }
virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n) 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; size_type new_count;
if(first_n){ if(first_n){
new_count = division_count; new_count = division_count;
} }
else{ else{
BOOST_ASSERT(difference_type(count_)>= division_count); BOOST_ASSERT(difference_type(this->count_)>= division_count);
new_count = count_ - division_count; new_count = this->count_ - division_count;
} }
//This function should never called with a count different to zero //This function should never called with a count different to zero
BOOST_ASSERT(new_count == 0); BOOST_ASSERT(new_count == 0);
@@ -147,21 +148,21 @@ struct default_construct_aux_proxy
private: private:
void priv_uninitialized_copy(Iterator p, const size_type n) void priv_uninitialized_copy(Iterator p, const size_type n)
{ {
BOOST_ASSERT(n <= count_); BOOST_ASSERT(n <= this->count_);
Iterator orig_p = p; Iterator orig_p = p;
size_type i = 0; size_type i = 0;
try{ try{
for(; i < n; ++i, ++p){ 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(...){ catch(...){
while(i--){ 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; throw;
} }
count_ -= n; this->count_ -= n;
} }
A &a_; A &a_;
size_type count_; size_type count_;
@@ -223,13 +224,13 @@ struct advanced_insert_aux_non_movable_emplace
{ {
BOOST_ASSERT(division_count <=1); BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){ if(!this->used_){
alloc_traits::construct( a_ alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p) , container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail:: , ::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> template<int ...IdxPack>
void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p) void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{ {
if(!used_){ if(!this->used_){
alloc_traits::construct( a_ alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p) , container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail:: , ::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...> : public advanced_insert_aux_non_movable_emplace<A, Iterator, Args...>
{ {
typedef advanced_insert_aux_non_movable_emplace<A, Iterator, Args...> base_t; 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::value_type value_type;
typedef typename base_t::difference_type difference_type; typedef typename base_t::difference_type difference_type;
typedef typename base_t::index_tuple_t index_tuple_t; typedef typename base_t::index_tuple_t index_tuple_t;
explicit advanced_insert_aux_emplace(A &a, Args&&... args) 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() ~advanced_insert_aux_emplace()
@@ -283,8 +285,13 @@ struct advanced_insert_aux_emplace
void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p) void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{ {
if(!this->used_){ if(!this->used_){
*p = boost::move(value_type ( aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...)); 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; this->used_ = true;
} }
} }
@@ -295,8 +302,17 @@ struct advanced_insert_aux_emplace
BOOST_ASSERT(division_count <=1); BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!this->used_){ if(!this->used_){
*p = boost::move(value_type( aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...)); 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; 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) \ virtual void uninitialized_copy_remaining_to(Iterator p) \
{ \ { \
if(!used_){ \ if(!this->used_){ \
alloc_traits::construct \ alloc_traits::construct \
( a_ \ ( this->a_ \
, container_detail::to_raw_pointer(&*p) \ , container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ 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); \ BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \ if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \ if(!this->used_){ \
alloc_traits::construct \ alloc_traits::construct \
( a_ \ ( this->a_ \
, container_detail::to_raw_pointer(&*p) \ , container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ 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; \ <A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > base_t; \
typedef typename base_t::value_type value_type; \ typedef typename base_t::value_type value_type; \
typedef typename base_t::difference_type difference_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) \ BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ ( 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) \ virtual void copy_remaining_to(Iterator p) \
{ \ { \
if(!this->used_){ \ if(!this->used_){ \
value_type v BOOST_PP_LPAREN_IF(n) \ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
BOOST_PP_RPAREN_IF(n); \ alloc_traits::construct(this->a_, vp \
*p = boost::move(v); \ 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; \ 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); \ BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \ if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!this->used_){ \ if(!this->used_){ \
value_type v BOOST_PP_LPAREN_IF(n) \ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
BOOST_PP_RPAREN_IF(n); \ alloc_traits::construct(this->a_, vp \
*p = boost::move(v); \ 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; \ 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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // 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 : 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 : 4671) // the copy constructor is inaccessible
#pragma warning (disable : 4584) // X is already a base-class of Y
#endif //BOOST_MSVC #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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
@@ -21,7 +21,7 @@
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/version_type.hpp> #include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/utilities.hpp> #include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
@@ -85,6 +85,9 @@ struct scoped_destructor_n
void increment_size(size_type inc) void increment_size(size_type inc)
{ m_n += inc; } { m_n += inc; }
void increment_size_backwards(size_type inc)
{ m_n += inc; m_p -= inc; }
~scoped_destructor_n() ~scoped_destructor_n()
{ {
@@ -115,10 +118,38 @@ struct null_scoped_destructor_n
void increment_size(size_type) void increment_size(size_type)
{} {}
void increment_size_backwards(size_type)
{}
void release() 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> template <class Allocator>
class allocator_destroyer 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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) 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) 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) Data(const Compare &comp)
@@ -185,6 +193,14 @@ class flat_tree
: m_data(boost::move(x.m_data)) : 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> template <class InputIterator>
flat_tree( ordered_range_t, InputIterator first, InputIterator last flat_tree( ordered_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare() , const Compare& comp = Compare()
@@ -285,7 +301,6 @@ class flat_tree
return ret; return ret;
} }
iterator insert_equal(const value_type& val) iterator insert_equal(const value_type& val)
{ {
iterator i = this->upper_bound(KeyOfValue()(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) iterator insert_equal(const_iterator pos, const value_type& val)
{ {
insert_commit_data data; 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); return priv_insert_commit(data, val);
} }
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval) iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
{ {
insert_commit_data data; 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)); return priv_insert_commit(data, boost::move(mval));
} }
@@ -346,7 +361,15 @@ class flat_tree
{ {
typedef typename typedef typename
std::iterator_traits<InIt>::iterator_category ItCat; 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 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -390,7 +413,7 @@ class flat_tree
{ {
value_type &&val = value_type(boost::forward<Args>(args)...); value_type &&val = value_type(boost::forward<Args>(args)...);
insert_commit_data data; 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)); 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); \ BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \ value_type &val = vval; \
insert_commit_data data; \ 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)); \ return priv_insert_commit(data, boost::move(val)); \
} \ } \
//! //!
@@ -730,10 +753,39 @@ class flat_tree
return std::pair<RanIt, RanIt>(first, first); return std::pair<RanIt, RanIt>(first, first);
} }
template <class FwdIt> template <class BidirIt>
void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag) 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)); 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->reserve(this->size()+len);
this->priv_insert_equal(first, last, std::input_iterator_tag()); 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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (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. // (C) Copyright Gennaro Prota 2003 - 2004.
// //
// Distributed under the Boost Software License, Version 1.0. // Distributed under the Boost Software License, Version 1.0.
@@ -21,7 +21,7 @@
#include "config_begin.hpp" #include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <boost/container/allocator/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp> #include <boost/container/detail/variadic_templates_tools.hpp>
@@ -513,7 +513,7 @@ struct emplace_functor
container_detail::tuple<Args&...> args_; container_detail::tuple<Args&...> args_;
}; };
#else #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \ #define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template <) \ BOOST_PP_EXPR_IF(n, template <) \
@@ -522,16 +522,16 @@ struct emplace_functor
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
{ \ { \
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_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \ BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
\ \
template<class A, class T> \ template<class A, class T> \
void operator()(A &a, T *ptr) \ void operator()(A &a, T *ptr) \
{ \ { \
allocator_traits<A>::construct \ 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) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)

View File

@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// (C) Copyright Stephen Cleary 2000. // (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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/version_type.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.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/mpl.hpp>
#include <boost/container/detail/destroyers.hpp> #include <boost/container/detail/destroyers.hpp>
@@ -36,6 +36,7 @@
#endif #endif
#include <boost/container/detail/algorithms.hpp> #include <boost/container/detail/algorithms.hpp>
#include <new>
namespace boost { namespace boost {
@@ -259,47 +260,21 @@ struct node_alloc_holder
void deallocate_one(const NodePtr &p, allocator_v2) void deallocate_one(const NodePtr &p, allocator_v2)
{ this->node_alloc().deallocate_one(p); } { 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 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
/*
template<class A, class ...Args>
static void construct(A &a, const NodePtr &ptr, Args &&...args)
{
}
*/
template<class ...Args> template<class ...Args>
NodePtr create_node(Args &&...args) NodePtr create_node(Args &&...args)
{ {
NodePtr p = this->allocate_one(); NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc()); Deallocator node_deallocator(p, this->node_alloc());
allocator_traits<NodeAlloc>::construct 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(); 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); return (p);
} }
@@ -313,9 +288,11 @@ struct node_alloc_holder
NodePtr p = this->allocate_one(); \ NodePtr p = this->allocate_one(); \
Deallocator node_deallocator(p, this->node_alloc()); \ Deallocator node_deallocator(p, this->node_alloc()); \
allocator_traits<NodeAlloc>::construct \ 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, _)); \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
node_deallocator.release(); \ 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); \ return (p); \
} \ } \
//! //!
@@ -329,8 +306,11 @@ struct node_alloc_holder
{ {
NodePtr p = this->allocate_one(); NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc()); 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(); 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); return (p);
} }
@@ -364,8 +344,11 @@ struct node_alloc_holder
mem.pop_front(); mem.pop_front();
//This can throw //This can throw
constructed = 0; 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; ++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) //This can throw in some containers (predicate might throw)
inserter(*p); 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,8 @@
#include "config_begin.hpp" #include "config_begin.hpp"
#include <boost/container/detail/workaround.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/mpl.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
@@ -62,6 +64,33 @@ struct pair_nat;
struct piecewise_construct_t { }; struct piecewise_construct_t { };
static const piecewise_construct_t piecewise_construct = 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> template <class T1, class T2>
struct pair struct pair
{ {
@@ -79,47 +108,40 @@ struct pair
pair() pair()
: first(), second() : 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 copy assignment
pair(const pair& x) pair(const pair& x)
: first(x.first), second(x.second) : 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 move constructor
pair(BOOST_RV_REF(pair) p) pair(BOOST_RV_REF(pair) p)
: first(::boost::move(p.first)), second(::boost::move(p.second)) : first(::boost::move(p.first)), second(::boost::move(p.second))
{} {}
template <class D, class S> 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)) : 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) pair(const std::pair<T1, T2>& x)
: first(x.first), second(x.second) : first(x.first), second(x.second)
{} {}
@@ -129,17 +151,20 @@ struct pair
: first(p.first), second(p.second) : first(p.first), second(p.second)
{} {}
//std::pair move constructor pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
template <class D, class S>
pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
: first(::boost::move(p.first)), second(::boost::move(p.second)) : 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)) : first(::boost::move(p.first)), second(::boost::move(p.second))
{} {}
//piecewise_construct missing //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 //Variadic versions
template<class U> template<class U>
@@ -179,14 +204,6 @@ struct pair
return *this; 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 move assignment
pair& operator=(BOOST_RV_REF(pair) p) pair& operator=(BOOST_RV_REF(pair) p)
{ {
@@ -196,7 +213,23 @@ struct pair
} }
template <class D, class S> 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); first = ::boost::move(p.first);
second = ::boost::move(p.second); second = ::boost::move(p.second);
@@ -220,7 +253,7 @@ struct pair
} }
//std::pair move assignment //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); first = ::boost::move(p.first);
second = ::boost::move(p.second); second = ::boost::move(p.second);
@@ -228,7 +261,7 @@ struct pair
} }
template <class D, class S> 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); first = ::boost::move(p.first);
second = ::boost::move(p.second); 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 #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 #ifndef BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM(U, u) \ #define BOOST_CONTAINER_PP_PARAM(U, u) \
U && u \ U && u \
@@ -74,17 +78,16 @@
#ifndef BOOST_NO_RVALUE_REFERENCES #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) \ #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) )) \ 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) \ #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) )) \ 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 #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) #else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \ #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) #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) \ #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) \ #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) \ #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) \ #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) \ #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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. // (C) Copyright Gennaro Prota 2003 - 2004.
// //
// Distributed under the Boost Software License, Version 1.0. // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/destroyers.hpp>
#include <boost/container/detail/pair.hpp> #include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.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 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp> #include <boost/container/detail/preprocessor.hpp>
#endif #endif
@@ -90,70 +90,38 @@ struct rbtree_hook
>::type type; >::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> template<class T>
struct rbtree_type struct rbtree_internal_data_type
{ {
typedef T type; typedef T type;
}; };
template<class T1, class T2> 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; typedef pair<T1, T2> type;
}; };
//The node to be store in the tree
template <class T, class VoidPointer> template <class T, class VoidPointer>
struct rbtree_node struct rbtree_node
: public rbtree_hook<VoidPointer>::type : public rbtree_hook<VoidPointer>::type
{ {
private: private:
BOOST_COPYABLE_AND_MOVABLE(rbtree_node) //BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
rbtree_node();
public: public:
typedef typename rbtree_hook<VoidPointer>::type hook_type; typedef typename rbtree_hook<VoidPointer>::type hook_type;
typedef T value_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; 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 &get_data()
{ {
T* ptr = reinterpret_cast<T*>(&this->m_data); T* ptr = reinterpret_cast<T*>(&this->m_data);
@@ -166,7 +134,6 @@ struct rbtree_node
return *ptr; return *ptr;
} }
private:
internal_type m_data; internal_type m_data;
template<class A, class B> template<class A, class B>
@@ -188,22 +155,22 @@ struct rbtree_node
{ m_data = v; } { m_data = v; }
template<class A, class B> 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); const_cast<A&>(m_data.first) = ::boost::move(p.first);
m_data.second = boost::move(p.second); m_data.second = ::boost::move(p.second);
} }
template<class A, class B> 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); const_cast<A&>(m_data.first) = ::boost::move(p.first);
m_data.second = boost::move(p.second); m_data.second = ::boost::move(p.second);
} }
template<class V> template<class V>
void do_move(V &v) void do_move_assign(V &v)
{ m_data = boost::move(v); } { m_data = ::boost::move(v); }
}; };
}//namespace container_detail { }//namespace container_detail {
@@ -282,7 +249,7 @@ class rbtree
//First recycle a node (this can't throw) //First recycle a node (this can't throw)
try{ try{
//This can throw //This can throw
*p = other; p->do_assign(other.m_data);
return p; return p;
} }
catch(...){ catch(...){
@@ -295,7 +262,7 @@ class rbtree
} }
} }
else{ 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) //First recycle a node (this can't throw)
try{ try{
//This can throw //This can throw
*p = boost::move(other); p->do_move_assign(const_cast<Node &>(other).m_data);
return p; return p;
} }
catch(...){ catch(...){
@@ -332,7 +299,7 @@ class rbtree
} }
} }
else{ else{
return m_holder.create_node(other); return m_holder.create_node(other.m_data);
} }
} }
@@ -478,8 +445,10 @@ class rbtree
iterator(){} iterator(){}
//Pointer like operators //Pointer like operators
reference operator*() const { return this->m_it->get_data(); } reference operator*() const
pointer operator->() const { return pointer(&this->m_it->get_data()); } { return this->m_it->get_data(); }
pointer operator->() const
{ return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data()); }
//Increment / Decrement //Increment / Decrement
iterator& operator++() iterator& operator++()
@@ -532,9 +501,28 @@ class rbtree
} }
rbtree(BOOST_RV_REF(rbtree) x) 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() ~rbtree()
{} //AllocHolder clears the tree {} //AllocHolder clears the tree
@@ -552,7 +540,7 @@ class rbtree
//Transfer all the nodes to a temporary tree //Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed //If anything goes wrong, all the nodes will be destroyed
//automatically //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 //Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from this->icont().clone_from
@@ -578,7 +566,7 @@ class rbtree
if(this_alloc == x_alloc){ if(this_alloc == x_alloc){
//Destroy and swap pointers //Destroy and swap pointers
this->clear(); this->clear();
this->icont() = boost::move(x.icont()); this->icont() = ::boost::move(x.icont());
//Move allocator if needed //Move allocator if needed
this->AllocHolder::move_assign_alloc(x); this->AllocHolder::move_assign_alloc(x);
} }
@@ -587,7 +575,7 @@ class rbtree
//Transfer all the nodes to a temporary tree //Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed //If anything goes wrong, all the nodes will be destroyed
//automatically //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 //Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from this->icont().clone_from
@@ -872,9 +860,9 @@ class rbtree
if(this->empty()){ if(this->empty()){
//Insert with end hint, to achieve linear //Insert with end hint, to achieve linear
//complexity if [first, last) is ordered //complexity if [first, last) is ordered
const_iterator end(this->end()); const_iterator hint(this->cend());
for( ; first != last; ++first) for( ; first != last; ++first)
this->insert_unique(end, *first); hint = this->insert_unique(hint, *first);
} }
else{ else{
for( ; first != last; ++first) for( ; first != last; ++first)
@@ -913,9 +901,9 @@ class rbtree
{ {
//Insert with end hint, to achieve linear //Insert with end hint, to achieve linear
//complexity if [first, last) is ordered //complexity if [first, last) is ordered
const_iterator end(this->cend()); const_iterator hint(this->cend());
for( ; first != last; ++first) for( ; first != last; ++first)
this->insert_equal(end, *first); hint = this->insert_equal(hint, *first);
} }
iterator erase(const_iterator position) iterator erase(const_iterator position)

View File

@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000. // (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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,13 @@ namespace container_detail {
struct nat{}; 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 //boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative //need an alternative
template <typename T> struct alignment_of; 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/move/move.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <algorithm> #include <algorithm>
namespace boost { namespace boost {
namespace container { namespace container {
namespace container_detail { 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> template<class T>
const T &max_value(const T &a, const T &b) const T &max_value(const T &a, const T &b)
{ return a > b ? a : 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); return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
} }
} //namespace container { } //namespace container {
} //namespace boost { } //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. // Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at // (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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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) #define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
#endif #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> #include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/container/detail/flat_tree.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp> #include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.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> #include <boost/move/move.hpp>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -165,8 +165,13 @@ class flat_map
get_flat_tree_iterators get_flat_tree_iterators
<pointer>::const_reverse_iterator const_reverse_iterator; <pointer>::const_reverse_iterator const_reverse_iterator;
typedef A allocator_type; typedef A allocator_type;
//!Standard extension
typedef A stored_allocator_type; typedef A stored_allocator_type;
//!Standard extension for C++03 compilers with non-movable std::pair
typedef impl_value_type movable_value_type;
public: public:
//! <b>Effects</b>: Default constructs an empty flat_map. //! <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>Effects</b>: Copy constructs a flat_map.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <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) {} : m_flat_tree(x.m_flat_tree) {}
//! <b>Effects</b>: Move constructs a flat_map. //! <b>Effects</b>: Move constructs a flat_map.
//! Constructs *this using x's resources. //! Constructs *this using x's resources.
//! //!
//! <b>Complexity</b>: Construct. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Postcondition</b>: x is emptied. //! <b>Postcondition</b>: x is emptied.
flat_map(BOOST_RV_REF(flat_map) x) flat_map(BOOST_RV_REF(flat_map) x)
: m_flat_tree(boost::move(x.m_flat_tree)) : 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>Effects</b>: Makes *this a copy of x.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <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; } { m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: Move constructs a flat_map. //! <b>Effects</b>: Move constructs a flat_map.
@@ -234,7 +254,7 @@ class flat_map
//! <b>Complexity</b>: Construct. //! <b>Complexity</b>: Construct.
//! //!
//! <b>Postcondition</b>: x is emptied. //! <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; } { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out //! <b>Effects</b>: Returns the comparison object out
@@ -484,7 +504,7 @@ class flat_map
//! to the elements with bigger keys than x. //! to the elements with bigger keys than x.
//! //!
//! <b>Note</b>: If an element is inserted it might invalidate elements. //! <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> > return container_detail::force<std::pair<iterator,bool> >
(m_flat_tree.insert_unique(boost::move(x))); (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. //! <b>Note</b>: If an element is inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) 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. //! <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. //! 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. //! 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. //! <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>( return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(x))); 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 //! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x) 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>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const 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. //! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size(). //! capacity() is always greater than or equal to size().
@@ -916,6 +939,8 @@ class flat_multimap
typedef A allocator_type; typedef A allocator_type;
//Non-standard extension //Non-standard extension
typedef A stored_allocator_type; 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. //! <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>Effects</b>: Copy constructs a flat_multimap.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <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) { } : m_flat_tree(x.m_flat_tree) { }
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources. //! <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. //! <b>Postcondition</b>: x is emptied.
flat_multimap(BOOST_RV_REF(flat_multimap) x) flat_multimap(BOOST_RV_REF(flat_multimap) x)
: m_flat_tree(boost::move(x.m_flat_tree)) : 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>Effects</b>: Makes *this a copy of x.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <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; } { m_flat_tree = x.m_flat_tree; return *this; }
//! <b>Effects</b>: this->swap(x.get()). //! <b>Effects</b>: this->swap(x.get()).
//! //!
//! <b>Complexity</b>: Constant. //! <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; } { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out //! <b>Effects</b>: Returns the comparison object out
@@ -1359,14 +1399,14 @@ class flat_multimap
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x) 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>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//! //!
//! <b>Complexity</b>: Logarithmic //! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator> std::pair<const_iterator,const_iterator>
equal_range(const key_type& x) const 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. //! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size(). //! 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_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. //! <b>Complexity</b>: Constant.
explicit flat_set() explicit flat_set()
: m_flat_tree() : 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. //! comparison object and allocator.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
@@ -116,7 +116,7 @@ class flat_set
: m_flat_tree(comp, a) : 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 ). //! allocator, and inserts elements from the range [first ,last ).
//! //!
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using //! <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) : 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(). //! <b>Complexity</b>: Linear in x.size().
flat_set(const flat_set<T,Pred,A>& x) flat_set(const flat_set& x)
: m_flat_tree(x.m_flat_tree) {} : 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. //! <b>Postcondition</b>: x is emptied.
flat_set(BOOST_RV_REF(flat_set) mx) flat_set(BOOST_RV_REF(flat_set) mx)
: m_flat_tree(boost::move(mx.m_flat_tree)) : 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(). //! <b>Complexity</b>: Linear in x.size().
flat_set<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x) flat_set(const flat_set& x, const allocator_type &a)
{ m_flat_tree = x.m_flat_tree; return *this; } : 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>Effects</b>: Makes *this a copy of x.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <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; } { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out //! <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::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_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. //! <b>Complexity</b>: Constant.
explicit flat_multiset() explicit flat_multiset()
@@ -761,17 +777,47 @@ class flat_multiset
: m_flat_tree(ordered_range, first, last, comp, a) : m_flat_tree(ordered_range, first, last, comp, a)
{} {}
flat_multiset(const flat_multiset<T,Pred,A>& x) //! <b>Effects</b>: Copy constructs a flat_multiset.
: m_flat_tree(x.m_flat_tree) {} //!
//! <b>Complexity</b>: Linear in x.size().
flat_multiset(BOOST_RV_REF(flat_multiset) x) flat_multiset(const flat_multiset& x)
: m_flat_tree(boost::move(x.m_flat_tree)) : 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; } { 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; } { m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
//! <b>Effects</b>: Returns the comparison object out //! <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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 struct list_node
: public list_hook<VoidPointer>::type : public list_hook<VoidPointer>::type
{ {
typedef typename list_hook<VoidPointer>::type hook_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
T m_data; T m_data;
}; };
@@ -374,6 +351,34 @@ class list
: AllocHolder(boost::move(static_cast<AllocHolder&>(x))) : 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 //! <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. //! 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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) : m_tree(first, last, comp, a, true)
{ {
//Allocator type must be std::pair<CONST Key, T> //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 //! <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) : m_tree(ordered_range, first, last, comp, a)
{ {
//Allocator type must be std::pair<CONST Key, T> //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>Effects</b>: Copy constructs a map.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <b>Complexity</b>: Linear in x.size().
map(const map<Key,T,Pred,A>& x) map(const map& x)
: m_tree(x.m_tree) : m_tree(x.m_tree)
{ {
//Allocator type must be std::pair<CONST Key, T> //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>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. //! <b>Postcondition</b>: x is emptied.
map(BOOST_RV_REF(map) x) map(BOOST_RV_REF(map) x)
: m_tree(boost::move(x.m_tree)) : m_tree(boost::move(x.m_tree))
{ {
//Allocator type must be std::pair<CONST Key, T> //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. //! <b>Effects</b>: Makes *this a copy of x.
@@ -833,7 +856,7 @@ class multimap
: m_tree(comp, a) : m_tree(comp, a)
{ {
//Allocator type must be std::pair<CONST Key, T> //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 //! <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) : m_tree(first, last, comp, a, false)
{ {
//Allocator type must be std::pair<CONST Key, T> //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 //! <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) : m_tree(ordered_range, first, last, comp, a)
{} {}
//! <b>Effects</b>: Copy constructs a multimap. //! <b>Effects</b>: Copy constructs a multimap.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <b>Complexity</b>: Linear in x.size().
multimap(const multimap<Key,T,Pred,A>& x) multimap(const multimap& x)
: m_tree(x.m_tree) : m_tree(x.m_tree)
{ {
//Allocator type must be std::pair<CONST Key, T> //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>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. //! <b>Postcondition</b>: x is emptied.
multimap(BOOST_RV_REF(multimap) x) multimap(BOOST_RV_REF(multimap) x)
: m_tree(boost::move(x.m_tree)) : m_tree(boost::move(x.m_tree))
{ {
//Allocator type must be std::pair<CONST Key, T> //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. //! <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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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>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. //! <b>Postcondition</b>: x is emptied.
set(BOOST_RV_REF(set) x) set(BOOST_RV_REF(set) x)
: m_tree(boost::move(x.m_tree)) : 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(). //! <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) set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
{ m_tree = x.m_tree; return *this; } { 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>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. //! <b>Postcondition</b>: x is emptied.
multiset(BOOST_RV_REF(multiset) x) multiset(BOOST_RV_REF(multiset) x)
: m_tree(boost::move(x.m_tree)) : 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>Effects</b>: Makes *this a copy of x.
//! //!
//! <b>Complexity</b>: Linear in x.size(). //! <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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 struct slist_node
: public slist_hook<VoidPointer>::type : public slist_hook<VoidPointer>::type
{ {
typedef typename slist_hook<VoidPointer>::type hook_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
T m_data; T m_data;
}; };
@@ -391,6 +367,34 @@ class slist
: AllocHolder(boost::move(static_cast<AllocHolder&>(x))) : 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>Effects</b>: Makes *this contain the same elements as x.
//! //!
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy //! <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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/utilities.hpp>
#include <boost/container/detail/iterators.hpp> #include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.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 <boost/intrusive/pointer_traits.hpp>
#include <algorithm> #include <algorithm>
@@ -78,10 +78,6 @@ struct smart_ptr_type<T*>
{ return ptr;} { 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> template <class C>
class clear_on_destroy class clear_on_destroy
{ {
@@ -110,13 +106,10 @@ class clear_on_destroy
template<class VoidPtr> template<class VoidPtr>
struct node_type_base struct node_type_base
{/* {
node_type_base(VoidPtr p)
: up(p)
{}*/
node_type_base() node_type_base()
{} {}
void set_pointer(VoidPtr p) void set_pointer(const VoidPtr &p)
{ up = p; } { up = p; }
VoidPtr up; VoidPtr up;
@@ -126,33 +119,6 @@ template<typename VoidPointer, typename T>
struct node_type struct node_type
: public node_type_base<VoidPointer> : 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; T value;
}; };
@@ -206,17 +172,17 @@ class iterator
private: private:
static node_type_ptr_t node_ptr_cast(const void_ptr &p) 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) 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) 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 reference dereference() const
@@ -353,35 +319,37 @@ BOOST_JOIN(check_invariant_,__LINE__).touch();
/// @endcond /// @endcond
//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector //! Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
//!drop-in replacement implemented as a node container, offering iterator and reference //! drop-in replacement implemented as a node container, offering iterator and reference
//!stability. //! 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 //! We present stable_vector, a fully STL-compliant stable container that provides
//!most of the features of std::vector except element contiguity. //! most of the features of std::vector except element contiguity.
//! //!
//!General properties: stable_vector satisfies all the requirements of a container, //! General properties: stable_vector satisfies all the requirements of a container,
//!a reversible container and a sequence and provides all the optional operations //! a reversible container and a sequence and provides all the optional operations
//!present in std::vector. Like std::vector, iterators are random access. //! present in std::vector. Like std::vector, iterators are random access.
//!stable_vector does not provide element contiguity; in exchange for this absence, //! 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 //! 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 //! 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 //! assigned the return value of end() always remain valid until the destruction of
//!the associated stable_vector. //! the associated stable_vector.
//! //!
//!Operation complexity: The big-O complexities of stable_vector operations match //! Operation complexity: The big-O complexities of stable_vector operations match
//!exactly those of std::vector. In general, insertion/deletion is constant time at //! 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 //! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
//!does not internally perform any value_type destruction, copy or assignment //! does not internally perform any value_type destruction, copy or assignment
//!operations other than those exactly corresponding to the insertion of new //! operations other than those exactly corresponding to the insertion of new
//!elements or deletion of stored elements, which can sometimes compensate in terms //! 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 //! of performance for the extra burden of doing more pointer manipulation and an
//!additional allocation per element. //! additional allocation per element.
//! //!
//!Exception safety: As stable_vector does not internally copy elements around, some //! Exception safety: As stable_vector does not internally copy elements around, some
//!operations provide stronger exception safety guarantees than in std::vector: //! operations provide stronger exception safety guarantees than in std::vector:
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class A = std::allocator<T> >
#else #else
@@ -524,7 +492,7 @@ class stable_vector
//! <b>Throws</b>: If allocator_type's copy constructor throws. //! <b>Throws</b>: If allocator_type's copy constructor throws.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
explicit stable_vector(const A& al) explicit stable_vector(const allocator_type& al)
: internal_data(al),impl(al) : internal_data(al),impl(al)
{ {
STABLE_VECTOR_CHECK_INVARIANT; STABLE_VECTOR_CHECK_INVARIANT;
@@ -538,7 +506,7 @@ class stable_vector
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
explicit stable_vector(size_type 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); stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n); this->resize(n);
@@ -553,7 +521,7 @@ class stable_vector
//! throws or T's default or copy constructor throws. //! throws or T's default or copy constructor throws.
//! //!
//! <b>Complexity</b>: Linear to n. //! <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) : internal_data(al),impl(al)
{ {
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this); 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). //! <b>Complexity</b>: Linear to the range [first, last).
template <class InputIterator> 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) : internal_data(al),impl(al)
{ {
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this); stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -607,6 +575,40 @@ class stable_vector
this->priv_swap_members(x); 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 //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
//! and used memory is deallocated. //! and used memory is deallocated.
//! //!
@@ -709,7 +711,7 @@ class stable_vector
//! <b>Throws</b>: If allocator's copy constructor throws. //! <b>Throws</b>: If allocator's copy constructor throws.
//! //!
//! <b>Complexity</b>: Constant. //! <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. //! <b>Effects</b>: Returns a reference to the internal allocator.
//! //!
@@ -1137,7 +1139,7 @@ class stable_vector
void emplace_back(Args &&...args) void emplace_back(Args &&...args)
{ {
typedef emplace_functor<Args...> EmplaceFunctor; 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)...); EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); 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 //Just call more general insert(pos, size, value) and return iterator
size_type pos_n = position - cbegin(); size_type pos_n = position - cbegin();
typedef emplace_functor<Args...> EmplaceFunctor; 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)...); EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(position, EmplaceIterator(ef), EmplaceIterator()); this->insert(position, EmplaceIterator(ef), EmplaceIterator());
return iterator(this->begin() + pos_n); return iterator(this->begin() + pos_n);
@@ -1172,7 +1174,7 @@ class stable_vector
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ 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, >) \ BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \ 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) \ EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \ BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \ BOOST_PP_RPAREN_IF(n); \
@@ -1186,7 +1188,7 @@ class stable_vector
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ 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, >) \ BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
EmplaceFunctor; \ 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) \ EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \ BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \ BOOST_PP_RPAREN_IF(n); \
@@ -1482,12 +1484,12 @@ class stable_vector
static node_type_ptr_t node_ptr_cast(const void_ptr &p) 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) 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) static value_type& value(const void_ptr &p)
@@ -1529,7 +1531,9 @@ class stable_vector
{ {
node_type_ptr_t p = this->allocate_one(); node_type_ptr_t p = this->allocate_one();
try{ 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); p->set_pointer(up);
} }
catch(...){ catch(...){
@@ -1621,7 +1625,9 @@ class stable_vector
p = mem.front(); p = mem.front();
mem.pop_front(); mem.pop_front();
//This can throw //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])); p->set_pointer(void_ptr_ptr(&it[i]));
++first; ++first;
it[i] = p; it[i] = p;
@@ -1650,7 +1656,9 @@ class stable_vector
break; break;
} }
//This can throw //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])); p->set_pointer(void_ptr_ptr(&it[i]));
++first; ++first;
it[i]=p; 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/algorithms.hpp>
#include <boost/container/detail/version_type.hpp> #include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_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/container/detail/mpl.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
@@ -620,12 +620,12 @@ class basic_string
//! //!
//! <b>Postcondition</b>: x == *this. //! <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) basic_string(const basic_string& s)
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc())) : base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
{ this->priv_range_initialize(s.begin(), s.end()); } { 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. //! <b>Throws</b>: If allocator_type's copy constructor throws.
//! //!
@@ -634,6 +634,32 @@ class basic_string
: base_t(boost::move((base_t&)s)) : 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, //! <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. //! 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, 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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/iterators.hpp>
#include <boost/container/detail/algorithms.hpp> #include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/destroyers.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/container/container_fwd.hpp>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <boost/move/move_helpers.hpp> #include <boost/move/move_helpers.hpp>
@@ -46,6 +46,7 @@
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/advanced_insert_int.hpp> #include <boost/container/detail/advanced_insert_int.hpp>
#include <boost/assert.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
@@ -540,6 +541,40 @@ class vector : private container_detail::vector_alloc_holder<A>
: base_t(boost::move(mx.alloc())) : base_t(boost::move(mx.alloc()))
{ this->swap_members(mx); } { 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 //! <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. //! 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) 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 //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 Distributed under the 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 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 ->Change "insert" and "push_back"/"push_front" to catch non-const rvalues
->Add an example with stateful allocators ->Add an example with stateful allocators
->Add test to check convertible types in push_back/insert ->Add test to check convertible types in push_back/insert
->Add SCARY iterators.
Review allocator traits Review allocator traits
-> Explicit instantiation of simple allocator & std::allocator to detect missing allocator_traits calls
-> Avoid any rebind<>::other -> Avoid any rebind<>::other
-> Review select_on_container_copy_xxx -> Review select_on_container_copy_xxx
-> Review propagate_on_xxx -> Review propagate_on_xxx
@@ -12,13 +12,13 @@ Review allocator traits
-> Default + swap move constructors correct? -> Default + swap move constructors correct?
-> Review container documentation in swap/copy/move regarding allocators -> 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: Add and test:
Test different propagation values and with inequal allocators Test different propagation values and with inequal allocators
propagate_on_container_move_assignment propagate_on_container_move_assignment
select_on_container_copy_construction select_on_container_copy_construction
propagate_on_container_swap 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 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 Add initializer lists
Write forward_list 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 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 change virtual functions with pointers to avoid template instantiation for every type
All functions from base classes like vector_base, node_alloc_holder, etc., should be named with underscore or
similar to avoid namespace pollution.

View File

@@ -43,6 +43,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_test.vcpr
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject 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 Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug Debug = Debug
@@ -95,6 +103,14 @@ Global
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32 {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.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = 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 EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection

View File

@@ -179,6 +179,9 @@
<Filter <Filter
Name="container" Name="container"
Filter=""> Filter="">
<File
RelativePath="..\..\..\..\boost\container\allocator_traits.hpp">
</File>
<File <File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp"> RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File> </File>
@@ -197,6 +200,9 @@
<File <File
RelativePath="..\..\..\..\boost\container\map.hpp"> RelativePath="..\..\..\..\boost\container\map.hpp">
</File> </File>
<File
RelativePath="..\..\..\..\boost\container\scoped_allocator.hpp">
</File>
<File <File
RelativePath="..\..\..\..\boost\container\set.hpp"> RelativePath="..\..\..\..\boost\container\set.hpp">
</File> </File>
@@ -215,19 +221,6 @@
<File <File
RelativePath="..\..\..\..\boost\container\vector.hpp"> RelativePath="..\..\..\..\boost\container\vector.hpp">
</File> </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 <Filter
Name="detail" Name="detail"
Filter=""> Filter="">
@@ -264,6 +257,9 @@
<File <File
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp"> RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File> </File>
<File
RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
</File>
<File <File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp"> RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File> </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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 <boost/container/detail/config_begin.hpp>
#include <cstddef> #include <cstddef>
#include <boost/container/allocator/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/integral_constant.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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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) pointer address(reference value)
{ return pointer(addressof(value)); } { return pointer(container_detail::addressof(value)); }
const_pointer address(const_reference value) const 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) pointer allocate(size_type, cvoid_ptr = 0)
{ return 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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){ } , m_offset(other.m_offset), m_allocations(0){ }
pointer address(reference value) pointer address(reference value)
{ return pointer(addressof(value)); } { return pointer(container_detail::addressof(value)); }
const_pointer address(const_reference value) const 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) pointer allocate(size_type , cvoid_ptr hint = 0)
{ (void)hint; return 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
@@ -228,17 +228,17 @@ class recursive_flat_multiset
{ {
public: public:
recursive_flat_multiset(const recursive_flat_multiset &c) 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) recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
{ {
id_ = c.id_; id_ = c.id_;
flat_set_= c.flat_set_; flat_multiset_= c.flat_multiset_;
return *this; return *this;
} }
int id_; 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) friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
{ return a.id_ < b.id_; } { 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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; return 1;
if(!CheckEqualPairContainers(boostmultimap, stdmultimap)) if(!CheckEqualPairContainers(boostmultimap, stdmultimap))
return 1; return 1;
{ { //Check equal_range
IntType i1(i); std::pair<typename MyBoostMultiMap::iterator, typename MyBoostMultiMap::iterator> bret =
IntType i2(i); boostmultimap->equal_range(boostmultimap->begin()->first);
new(&intpair)IntPairType(boost::move(i1), boost::move(i2));
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); 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 //Now test move semantics
C original; C original;
original.emplace();
C move_ctor(boost::move(original)); C move_ctor(boost::move(original));
C move_assign; C move_assign;
move_assign.emplace();
move_assign = boost::move(move_ctor); move_assign = boost::move(move_ctor);
move_assign.swap(original); 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
@@ -95,6 +95,26 @@ enum Test
int main() 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(); recursive_vector_test();
{ {
//Now test move semantics //Now test move semantics
@@ -134,7 +154,8 @@ int main()
if(!boost::container::test::test_propagate_allocator<vector>()) if(!boost::container::test::test_propagate_allocator<vector>())
return 1; return 1;
return 0; return 0;
} }
#include <boost/container/detail/config_end.hpp> #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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //