mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 22:14:26 +02:00
Experimental scoped_allocator support
[SVN r77480]
This commit is contained in:
@@ -1,382 +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_ALLOCATOR_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_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/intrusive/pointer_traits.hpp>
|
||||
#include <boost/container/allocator/memory_util.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <limits> //numeric_limits<>::max()
|
||||
#include <new> //placement new
|
||||
#include <memory> //std::allocator
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
|
||||
///@cond
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
//workaround needed for C++03 compilers with no construct()
|
||||
//supporting rvalue references
|
||||
template<class A>
|
||||
struct is_std_allocator
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<class T>
|
||||
struct is_std_allocator< std::allocator<T> >
|
||||
{ static const bool value = true; };
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
///@endcond
|
||||
|
||||
template <typename Alloc>
|
||||
struct allocator_traits
|
||||
{
|
||||
//allocator_type
|
||||
typedef Alloc allocator_type;
|
||||
//value_type
|
||||
typedef typename Alloc::value_type value_type;
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//!Alloc::pointer if such a type exists; otherwise, value_type*
|
||||
//!
|
||||
typedef unspecified pointer;
|
||||
//!Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
|
||||
//!
|
||||
typedef unspecified const_pointer;
|
||||
//!Non-standard extension
|
||||
//!Alloc::reference if such a type exists; otherwise, value_type&
|
||||
typedef unspecified pointer;
|
||||
//!Non-standard extension
|
||||
//!Alloc::const_reference if such a type exists ; otherwise, const value_type&
|
||||
typedef unspecified const_pointer;
|
||||
//!Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
|
||||
//!
|
||||
typedef unspecified void_pointer;
|
||||
//!Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
|
||||
//!
|
||||
typedef unspecified const_void_pointer;
|
||||
//!Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
|
||||
//!
|
||||
typedef unspecified difference_type;
|
||||
//!Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
|
||||
//!
|
||||
typedef unspecified size_type;
|
||||
//!Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
|
||||
//!type with internal constant static member <pre>value</pre> == false.
|
||||
typedef unspecified propagate_on_container_copy_assignment;
|
||||
//!Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
|
||||
//!type with internal constant static member <pre>value</pre> == false.
|
||||
typedef unspecified propagate_on_container_move_assignment;
|
||||
//!Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
|
||||
//!type with internal constant static member <pre>value</pre> == false.
|
||||
typedef unspecified propagate_on_container_swap;
|
||||
//!Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
|
||||
//!if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
|
||||
//!more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
|
||||
//!
|
||||
//!In C++03 compilers <pre>rebind_alloc</pre> is a struct derived from an allocator
|
||||
//!deduced by previously detailed rules.
|
||||
template <class T> using rebind_alloc = unspecified;
|
||||
|
||||
//!In C++03 compilers <pre>rebind_traits</pre> is a struct derived from
|
||||
//!<pre>allocator_traits<OtherAlloc><pre>, where `OtherAlloc` is
|
||||
//!the allocator deduced by rules explained in `rebind_alloc`.
|
||||
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
|
||||
|
||||
//!Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
|
||||
//!`type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef unspecified_type type; };
|
||||
#else
|
||||
//pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
pointer, value_type*)
|
||||
pointer;
|
||||
//const_pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
|
||||
rebind_pointer<const value_type>)
|
||||
const_pointer;
|
||||
//reference
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
reference, typename container_detail::unvoid<value_type>::type&)
|
||||
reference;
|
||||
//const_reference
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
const_reference, const typename container_detail::unvoid<value_type>::type&)
|
||||
const_reference;
|
||||
//void_pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
|
||||
rebind_pointer<void>)
|
||||
void_pointer;
|
||||
//const_void_pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
|
||||
rebind_pointer<const void>)
|
||||
const_void_pointer;
|
||||
//difference_type
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
difference_type, std::ptrdiff_t)
|
||||
difference_type;
|
||||
//size_type
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
size_type, std::size_t)
|
||||
size_type;
|
||||
//propagate_on_container_copy_assignment
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
propagate_on_container_copy_assignment, boost::false_type)
|
||||
propagate_on_container_copy_assignment;
|
||||
//propagate_on_container_move_assignment
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
propagate_on_container_move_assignment, boost::false_type)
|
||||
propagate_on_container_move_assignment;
|
||||
//propagate_on_container_swap
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
|
||||
propagate_on_container_swap, boost::false_type)
|
||||
propagate_on_container_swap;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_ALIASES)
|
||||
//C++11
|
||||
template <typename T> using rebind_alloc = boost::intrusive::detail::type_rebinder<Alloc, T>::type;
|
||||
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
|
||||
#else //!defined(BOOST_NO_TEMPLATE_ALIASES)
|
||||
//Some workaround for C++03 or C++11 compilers with no template aliases
|
||||
template <typename T>
|
||||
struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type
|
||||
{
|
||||
typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base;
|
||||
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
template <typename... Args>
|
||||
rebind_alloc(Args&&... args)
|
||||
: Base(boost::forward<Args>(args)...)
|
||||
{}
|
||||
#else //!defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
: Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
|
||||
{} \
|
||||
//
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
#endif //!defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct rebind_traits
|
||||
: allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type>
|
||||
{};
|
||||
#endif //!defined(BOOST_NO_TEMPLATE_ALIASES)
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//!<b>Returns</b>: a.allocate(n)
|
||||
//!
|
||||
static pointer allocate(Alloc &a, size_type n)
|
||||
{ return a.allocate(n); }
|
||||
|
||||
//!<b>Returns</b>: a.deallocate(p, n)
|
||||
//!
|
||||
//!<b>Throws</b>: Nothing
|
||||
static void deallocate(Alloc &a, pointer p, size_type n)
|
||||
{ return a.deallocate(p, n); }
|
||||
|
||||
//!<b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
|
||||
//!otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
|
||||
static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_allocate
|
||||
<Alloc, const size_type, const const_void_pointer>::value;
|
||||
::boost::integral_constant<bool, value> flag;
|
||||
return allocator_traits::priv_allocate(flag, a, n, p);
|
||||
}
|
||||
|
||||
//!<b>Effects</b>: calls a.destroy(p) if that call is well-formed;
|
||||
//!otherwise, invokes `p->~T()`.
|
||||
template<class T>
|
||||
static void destroy(Alloc &a, T*p)
|
||||
{
|
||||
typedef T* destroy_pointer;
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_destroy
|
||||
<Alloc, const destroy_pointer>::value;
|
||||
::boost::integral_constant<bool, value> flag;
|
||||
allocator_traits::priv_destroy(flag, a, p);
|
||||
}
|
||||
|
||||
//!<b>Returns</b>: a.max_size() if that expression is well-formed; otherwise,
|
||||
//!`numeric_limits<size_type>::max()`.
|
||||
static size_type max_size(const Alloc &a)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_max_size
|
||||
<const Alloc>::value;
|
||||
::boost::integral_constant<bool, value> flag;
|
||||
return allocator_traits::priv_max_size(flag, a);
|
||||
}
|
||||
|
||||
//!<b>Returns</b>: a.select_on_container_copy_construction() if that expres sion is well- formed;
|
||||
//!otherwise, a.
|
||||
static Alloc select_on_container_copy_construction(const Alloc &a)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_select_on_container_copy_construction
|
||||
<const Alloc>::value;
|
||||
::boost::integral_constant<bool, value> flag;
|
||||
return allocator_traits::priv_select_on_container_copy_construction(flag, a);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//!Effects: calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed;
|
||||
//!otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
|
||||
template <class T, class ...Args>
|
||||
static void construct(Alloc & a, T* p, Args&&... args)
|
||||
{
|
||||
::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;
|
||||
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
private:
|
||||
static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
|
||||
{ return a.allocate(n, p); }
|
||||
|
||||
static pointer priv_allocate(boost::false_type, Alloc &a, size_type n, const_void_pointer)
|
||||
{ return allocator_traits::allocate(a, n); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(boost::true_type, Alloc &a, T* p)
|
||||
{ a.destroy(p); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(boost::false_type, Alloc &, T* p)
|
||||
{ p->~T(); (void)p; }
|
||||
|
||||
static size_type priv_max_size(boost::true_type, const Alloc &a)
|
||||
{ return a.max_size(); }
|
||||
|
||||
static size_type priv_max_size(boost::false_type, const Alloc &)
|
||||
{ return (std::numeric_limits<size_type>::max)(); }
|
||||
|
||||
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
|
||||
{ return a.select_on_container_copy_construction(); }
|
||||
|
||||
static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
|
||||
{ return a; }
|
||||
|
||||
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
|
||||
template<class T, class ...Args>
|
||||
static void priv_construct(boost::false_type, Alloc &a, T *p, Args && ...args)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_construct
|
||||
< Alloc, T*, Args... >::value;
|
||||
::boost::integral_constant<bool, value> flag;
|
||||
priv_construct_dispatch2(flag, a, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class T, class ...Args>
|
||||
static void priv_construct(boost::true_type, Alloc &a, T *p, Args && ...args)
|
||||
{
|
||||
priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class T, class ...Args>
|
||||
static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, Args && ...args)
|
||||
{ a.construct( p, ::boost::forward<Args>(args)...); }
|
||||
|
||||
template<class T, class ...Args>
|
||||
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, Args && ...args)
|
||||
{ ::new((void*)p) T(::boost::forward<Args>(args)...); }
|
||||
#else
|
||||
public:
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
|
||||
static void construct(Alloc &a, T *p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag; \
|
||||
allocator_traits::priv_construct(flag, a, p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
} \
|
||||
//
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
private:
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
|
||||
static void priv_construct(boost::false_type, Alloc &a, T *p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
|
||||
{ \
|
||||
const bool value = \
|
||||
boost::container::container_detail::has_member_function_callable_with_construct \
|
||||
< Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value; \
|
||||
::boost::integral_constant<bool, value> flag; \
|
||||
priv_construct_dispatch2(flag, a, p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||
} \
|
||||
\
|
||||
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
|
||||
static void priv_construct(boost::true_type, Alloc &a, T *p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
|
||||
{ \
|
||||
priv_construct_dispatch2(boost::false_type(), a, p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
|
||||
} \
|
||||
\
|
||||
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
|
||||
static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
|
||||
{ a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); } \
|
||||
\
|
||||
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
|
||||
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
{ ::new((void*)p) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
|
||||
//
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
#endif //BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
///@endcond
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
|
@@ -1,77 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_MEMORY_UTIL_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME select_on_container_copy_construction
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_void_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP)
|
@@ -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
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
@@ -896,6 +896,46 @@ class deque : protected deque_base<T, A>
|
||||
: Base(boost::move(static_cast<Base&>(x)))
|
||||
{ this->swap_members(x); }
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a vector using the specified allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation
|
||||
//! throws or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||
deque(const deque& x, const allocator_type &a)
|
||||
: Base(a)
|
||||
{
|
||||
if(x.size()){
|
||||
this->priv_initialize_map(x.size());
|
||||
boost::container::uninitialized_copy_alloc
|
||||
(this->alloc(), x.begin(), x.end(), this->members_.m_start);
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||
//! Moves mx's resources to *this if a == allocator_type().
|
||||
//! Otherwise copies values from x to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
|
||||
deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
|
||||
: Base(a)
|
||||
{
|
||||
if(mx.alloc() == a){
|
||||
this->swap_members(mx);
|
||||
}
|
||||
else{
|
||||
if(mx.size()){
|
||||
this->priv_initialize_map(mx.size());
|
||||
boost::container::uninitialized_copy_alloc
|
||||
(this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||
//! and inserts a copy of the range [first, last) in the deque.
|
||||
//!
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <iterator> //std::iterator_traits
|
||||
#include <boost/assert.hpp>
|
||||
@@ -41,7 +43,6 @@ template<class A, class FwdIt, class Iterator>
|
||||
struct advanced_insert_aux_proxy
|
||||
: public advanced_insert_aux_int<Iterator>
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
|
||||
@@ -54,36 +55,36 @@ struct advanced_insert_aux_proxy
|
||||
{}
|
||||
|
||||
virtual void copy_remaining_to(Iterator p)
|
||||
{ ::boost::copy_or_move(first_, last_, p); }
|
||||
{ ::boost::copy_or_move(this->first_, this->last_, p); }
|
||||
|
||||
virtual void uninitialized_copy_remaining_to(Iterator p)
|
||||
{ ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p); }
|
||||
{ ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); }
|
||||
|
||||
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
|
||||
{
|
||||
FwdIt mid = first_;
|
||||
FwdIt mid = this->first_;
|
||||
std::advance(mid, division_count);
|
||||
if(first_n){
|
||||
::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
|
||||
first_ = mid;
|
||||
::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
|
||||
this->first_ = mid;
|
||||
}
|
||||
else{
|
||||
::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
|
||||
last_ = mid;
|
||||
::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
|
||||
this->last_ = mid;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
|
||||
{
|
||||
FwdIt mid = first_;
|
||||
FwdIt mid = this->first_;
|
||||
std::advance(mid, division_count);
|
||||
if(first_n){
|
||||
::boost::copy_or_move(first_, mid, pos);
|
||||
first_ = mid;
|
||||
::boost::copy_or_move(this->first_, mid, pos);
|
||||
this->first_ = mid;
|
||||
}
|
||||
else{
|
||||
::boost::copy_or_move(mid, last_, pos);
|
||||
last_ = mid;
|
||||
::boost::copy_or_move(mid, this->last_, pos);
|
||||
this->last_ = mid;
|
||||
}
|
||||
}
|
||||
A &a_;
|
||||
@@ -95,7 +96,7 @@ template<class A, class Iterator>
|
||||
struct default_construct_aux_proxy
|
||||
: public advanced_insert_aux_int<Iterator>
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef ::boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename allocator_traits<A>::size_type size_type;
|
||||
typedef typename allocator_traits<A>::value_type value_type;
|
||||
typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
|
||||
@@ -109,11 +110,11 @@ struct default_construct_aux_proxy
|
||||
|
||||
virtual void copy_remaining_to(Iterator)
|
||||
{ //This should never be called with any count
|
||||
BOOST_ASSERT(count_ == 0);
|
||||
BOOST_ASSERT(this->count_ == 0);
|
||||
}
|
||||
|
||||
virtual void uninitialized_copy_remaining_to(Iterator p)
|
||||
{ this->priv_uninitialized_copy(p, count_); }
|
||||
{ this->priv_uninitialized_copy(p, this->count_); }
|
||||
|
||||
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
|
||||
{
|
||||
@@ -122,22 +123,22 @@ struct default_construct_aux_proxy
|
||||
new_count = division_count;
|
||||
}
|
||||
else{
|
||||
BOOST_ASSERT(difference_type(count_)>= division_count);
|
||||
new_count = count_ - division_count;
|
||||
BOOST_ASSERT(difference_type(this->count_)>= division_count);
|
||||
new_count = this->count_ - division_count;
|
||||
}
|
||||
this->priv_uninitialized_copy(pos, new_count);
|
||||
}
|
||||
|
||||
virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
|
||||
{
|
||||
BOOST_ASSERT(count_ == 0);
|
||||
BOOST_ASSERT(this->count_ == 0);
|
||||
size_type new_count;
|
||||
if(first_n){
|
||||
new_count = division_count;
|
||||
}
|
||||
else{
|
||||
BOOST_ASSERT(difference_type(count_)>= division_count);
|
||||
new_count = count_ - division_count;
|
||||
BOOST_ASSERT(difference_type(this->count_)>= division_count);
|
||||
new_count = this->count_ - division_count;
|
||||
}
|
||||
//This function should never called with a count different to zero
|
||||
BOOST_ASSERT(new_count == 0);
|
||||
@@ -147,21 +148,21 @@ struct default_construct_aux_proxy
|
||||
private:
|
||||
void priv_uninitialized_copy(Iterator p, const size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n <= count_);
|
||||
BOOST_ASSERT(n <= this->count_);
|
||||
Iterator orig_p = p;
|
||||
size_type i = 0;
|
||||
try{
|
||||
for(; i < n; ++i, ++p){
|
||||
alloc_traits::construct(a_, container_detail::to_raw_pointer(&*p));
|
||||
alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
while(i--){
|
||||
alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
|
||||
alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
|
||||
}
|
||||
throw;
|
||||
}
|
||||
count_ -= n;
|
||||
this->count_ -= n;
|
||||
}
|
||||
A &a_;
|
||||
size_type count_;
|
||||
@@ -223,13 +224,13 @@ struct advanced_insert_aux_non_movable_emplace
|
||||
{
|
||||
BOOST_ASSERT(division_count <=1);
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
|
||||
if(!used_){
|
||||
alloc_traits::construct( a_
|
||||
if(!this->used_){
|
||||
alloc_traits::construct( this->a_
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::container::container_detail::
|
||||
stored_ref<Args>::forward(get<IdxPack>(args_))...
|
||||
stored_ref<Args>::forward(get<IdxPack>(this->args_))...
|
||||
);
|
||||
used_ = true;
|
||||
this->used_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,13 +238,13 @@ struct advanced_insert_aux_non_movable_emplace
|
||||
template<int ...IdxPack>
|
||||
void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
|
||||
{
|
||||
if(!used_){
|
||||
alloc_traits::construct( a_
|
||||
if(!this->used_){
|
||||
alloc_traits::construct( this->a_
|
||||
, container_detail::to_raw_pointer(&*p)
|
||||
, ::boost::container::container_detail::
|
||||
stored_ref<Args>::forward(get<IdxPack>(args_))...
|
||||
stored_ref<Args>::forward(get<IdxPack>(this->args_))...
|
||||
);
|
||||
used_ = true;
|
||||
this->used_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +261,7 @@ struct advanced_insert_aux_emplace
|
||||
: public advanced_insert_aux_non_movable_emplace<A, Iterator, Args...>
|
||||
{
|
||||
typedef advanced_insert_aux_non_movable_emplace<A, Iterator, Args...> base_t;
|
||||
typedef boost::container::allocator_traits<A> alloc_traits;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::difference_type difference_type;
|
||||
typedef typename base_t::index_tuple_t index_tuple_t;
|
||||
@@ -283,8 +285,13 @@ struct advanced_insert_aux_emplace
|
||||
void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
|
||||
{
|
||||
if(!this->used_){
|
||||
*p = boost::move(value_type (
|
||||
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(this->a_, vp,
|
||||
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
|
||||
scoped_destructor<A> d(this->a_, vp);
|
||||
*p = boost::move(*vp);
|
||||
d.release();
|
||||
this->used_ = true;
|
||||
}
|
||||
}
|
||||
@@ -295,8 +302,17 @@ struct advanced_insert_aux_emplace
|
||||
BOOST_ASSERT(division_count <=1);
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
|
||||
if(!this->used_){
|
||||
*p = boost::move(value_type(
|
||||
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(this->a_, vp,
|
||||
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
|
||||
try {
|
||||
*p = boost::move(*vp);
|
||||
} catch (...) {
|
||||
alloc_traits::destroy(this->a_, vp);
|
||||
throw;
|
||||
}
|
||||
alloc_traits::destroy(this->a_, vp);
|
||||
this->used_ = true;
|
||||
}
|
||||
}
|
||||
@@ -337,13 +353,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), ar
|
||||
\
|
||||
virtual void uninitialized_copy_remaining_to(Iterator p) \
|
||||
{ \
|
||||
if(!used_){ \
|
||||
if(!this->used_){ \
|
||||
alloc_traits::construct \
|
||||
( a_ \
|
||||
( this->a_ \
|
||||
, container_detail::to_raw_pointer(&*p) \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
|
||||
); \
|
||||
used_ = true; \
|
||||
this->used_ = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -352,13 +368,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), ar
|
||||
{ \
|
||||
BOOST_ASSERT(division_count <=1); \
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
|
||||
if(!used_){ \
|
||||
if(!this->used_){ \
|
||||
alloc_traits::construct \
|
||||
( a_ \
|
||||
( this->a_ \
|
||||
, container_detail::to_raw_pointer(&*p) \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
|
||||
); \
|
||||
used_ = true; \
|
||||
this->used_ = true; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
@@ -382,6 +398,7 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
|
||||
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > base_t; \
|
||||
typedef typename base_t::value_type value_type; \
|
||||
typedef typename base_t::difference_type difference_type; \
|
||||
typedef boost::container::allocator_traits<A> alloc_traits; \
|
||||
\
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
|
||||
( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
@@ -391,10 +408,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
|
||||
virtual void copy_remaining_to(Iterator p) \
|
||||
{ \
|
||||
if(!this->used_){ \
|
||||
value_type v BOOST_PP_LPAREN_IF(n) \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
|
||||
BOOST_PP_RPAREN_IF(n); \
|
||||
*p = boost::move(v); \
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||
alloc_traits::construct(this->a_, vp \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
|
||||
scoped_destructor<A> d(this->a_, vp); \
|
||||
*p = boost::move(*vp); \
|
||||
d.release(); \
|
||||
this->used_ = true; \
|
||||
} \
|
||||
} \
|
||||
@@ -405,10 +425,13 @@ struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)
|
||||
BOOST_ASSERT(division_count <=1); \
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
|
||||
if(!this->used_){ \
|
||||
value_type v BOOST_PP_LPAREN_IF(n) \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
|
||||
BOOST_PP_RPAREN_IF(n); \
|
||||
*p = boost::move(v); \
|
||||
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
|
||||
alloc_traits::construct(this->a_, vp \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
|
||||
scoped_destructor<A> d(this->a_, vp); \
|
||||
*p = boost::move(*vp); \
|
||||
d.release(); \
|
||||
this->used_ = true; \
|
||||
} \
|
||||
} \
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -45,4 +45,5 @@
|
||||
// with /GR-; unpredictable behavior may result
|
||||
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
|
||||
#pragma warning (disable : 4671) // the copy constructor is inaccessible
|
||||
#pragma warning (disable : 4584) // X is already a base-class of Y
|
||||
#endif //BOOST_MSVC
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -85,6 +85,9 @@ struct scoped_destructor_n
|
||||
|
||||
void increment_size(size_type inc)
|
||||
{ m_n += inc; }
|
||||
|
||||
void increment_size_backwards(size_type inc)
|
||||
{ m_n += inc; m_p -= inc; }
|
||||
|
||||
~scoped_destructor_n()
|
||||
{
|
||||
@@ -115,10 +118,38 @@ struct null_scoped_destructor_n
|
||||
void increment_size(size_type)
|
||||
{}
|
||||
|
||||
void increment_size_backwards(size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
template<class A>
|
||||
class scoped_destructor
|
||||
{
|
||||
typedef boost::container::allocator_traits<A> AllocTraits;
|
||||
public:
|
||||
typedef typename A::value_type value_type;
|
||||
scoped_destructor(A &a, value_type *pv)
|
||||
: pv_(pv), a_(a)
|
||||
{}
|
||||
|
||||
~scoped_destructor()
|
||||
{
|
||||
if(pv_){
|
||||
AllocTraits::destroy(a_, pv_);
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{ pv_ = 0; }
|
||||
|
||||
private:
|
||||
value_type *pv_;
|
||||
A &a_;
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
class allocator_destroyer
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -102,11 +102,19 @@ class flat_tree
|
||||
{}
|
||||
|
||||
Data(const Data &d)
|
||||
: value_compare(d), m_vect(d.m_vect)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect)
|
||||
{}
|
||||
|
||||
Data(BOOST_RV_REF(Data) d)
|
||||
: value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
|
||||
{}
|
||||
|
||||
Data(const Data &d, const A &a)
|
||||
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
|
||||
{}
|
||||
|
||||
Data(BOOST_RV_REF(Data) d, const A &a)
|
||||
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
|
||||
{}
|
||||
|
||||
Data(const Compare &comp)
|
||||
@@ -185,6 +193,14 @@ class flat_tree
|
||||
: m_data(boost::move(x.m_data))
|
||||
{ }
|
||||
|
||||
flat_tree(const flat_tree& x, const allocator_type &a)
|
||||
: m_data(x.m_data, a)
|
||||
{ }
|
||||
|
||||
flat_tree(BOOST_RV_REF(flat_tree) x, const allocator_type &a)
|
||||
: m_data(boost::move(x.m_data), a)
|
||||
{ }
|
||||
|
||||
template <class InputIterator>
|
||||
flat_tree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
@@ -513,7 +513,7 @@ struct emplace_functor
|
||||
container_detail::tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
#else
|
||||
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
BOOST_PP_EXPR_IF(n, template <) \
|
||||
@@ -522,16 +522,16 @@ struct emplace_functor
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
{ \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
|
||||
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
||||
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
|
||||
\
|
||||
template<class A, class T> \
|
||||
void operator()(A &a, T *ptr) \
|
||||
{ \
|
||||
allocator_traits<A>::construct \
|
||||
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
|
||||
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
|
||||
} \
|
||||
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
|
||||
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
#include <new>
|
||||
|
||||
|
||||
namespace boost {
|
||||
@@ -259,47 +260,21 @@ struct node_alloc_holder
|
||||
|
||||
void deallocate_one(const NodePtr &p, allocator_v2)
|
||||
{ this->node_alloc().deallocate_one(p); }
|
||||
/*
|
||||
template<class A, class Convertible1, class Convertible2>
|
||||
static void construct(A &a, const NodePtr &ptr,
|
||||
BOOST_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
|
||||
{
|
||||
typedef typename Node::hook_type hook_type;
|
||||
typedef typename Node::value_type::first_type first_type;
|
||||
typedef typename Node::value_type::second_type second_type;
|
||||
Node *nodeptr = container_detail::to_raw_pointer(ptr);
|
||||
|
||||
//Hook constructor does not throw
|
||||
allocator_traits<A>::construct(a, static_cast<hook_type*>(nodeptr));
|
||||
|
||||
//Now construct pair members_holder
|
||||
value_type *valueptr = &nodeptr->get_data();
|
||||
allocator_traits<A>::construct(a, &valueptr->first, boost::move(value.first));
|
||||
BOOST_TRY{
|
||||
allocator_traits<A>::construct(a, &valueptr->second, boost::move(value.second));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
allocator_traits<A>::destroy(a, &valueptr->first);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
*/
|
||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
/*
|
||||
template<class A, class ...Args>
|
||||
static void construct(A &a, const NodePtr &ptr, Args &&...args)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
template<class ...Args>
|
||||
NodePtr create_node(Args &&...args)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
allocator_traits<NodeAlloc>::construct
|
||||
(this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward<Args>(args)...);
|
||||
( this->node_alloc()
|
||||
, container_detail::addressof(p->m_data), boost::forward<Args>(args)...);
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
@@ -313,9 +288,11 @@ struct node_alloc_holder
|
||||
NodePtr p = this->allocate_one(); \
|
||||
Deallocator node_deallocator(p, this->node_alloc()); \
|
||||
allocator_traits<NodeAlloc>::construct \
|
||||
(this->node_alloc(), container_detail::to_raw_pointer(p) \
|
||||
(this->node_alloc(), container_detail::addressof(p->m_data) \
|
||||
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
|
||||
node_deallocator.release(); \
|
||||
typedef typename Node::hook_type hook_type; \
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type; \
|
||||
return (p); \
|
||||
} \
|
||||
//!
|
||||
@@ -329,8 +306,11 @@ struct node_alloc_holder
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
|
||||
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
@@ -364,8 +344,11 @@ struct node_alloc_holder
|
||||
mem.pop_front();
|
||||
//This can throw
|
||||
constructed = 0;
|
||||
boost::container::construct_in_place(this->node_alloc(), p, beg);
|
||||
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
|
||||
++constructed;
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
|
||||
//This can throw in some containers (predicate might throw)
|
||||
inserter(*p);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -62,6 +62,33 @@ struct pair_nat;
|
||||
struct piecewise_construct_t { };
|
||||
static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
|
||||
/*
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
template <class U, class V> pair(pair<U, V>&& p);
|
||||
template <class... Args1, class... Args2>
|
||||
pair(piecewise_construct_t, tuple<Args1...> first_args,
|
||||
tuple<Args2...> second_args);
|
||||
|
||||
template <class U, class V> pair& operator=(const pair<U, V>& p);
|
||||
pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
|
||||
is_nothrow_move_assignable<T2>::value);
|
||||
template <class U, class V> pair& operator=(pair<U, V>&& p);
|
||||
|
||||
void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
|
||||
noexcept(swap(second, p.second)));
|
||||
};
|
||||
|
||||
template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
|
||||
*/
|
||||
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
@@ -79,47 +106,40 @@ struct pair
|
||||
pair()
|
||||
: first(), second()
|
||||
{}
|
||||
/*
|
||||
//pair from two values
|
||||
pair(const T1 &t1, const T2 &t2)
|
||||
: first(t1)
|
||||
, second(t2)
|
||||
{}
|
||||
|
||||
|
||||
//pair from two values
|
||||
pair(BOOST_RV_REF(T1) t1, BOOST_RV_REF(T2) t2)
|
||||
: first(::boost::move(t1))
|
||||
, second(::boost::move(t2))
|
||||
{}
|
||||
*/
|
||||
template<class U, class V>
|
||||
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
|
||||
: first(::boost::forward<U>(u))
|
||||
, second(::boost::forward<V>(v))
|
||||
{}
|
||||
|
||||
//pair copy assignment
|
||||
pair(const pair& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(const pair<D, S> &p)
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
//pair move constructor
|
||||
pair(BOOST_RV_REF(pair) p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
|
||||
pair(const pair<D, S> &p)
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
//std::pair copy constructor
|
||||
//pair from two values
|
||||
pair(const T1 &t1, const T2 &t2)
|
||||
: first(t1)
|
||||
, second(t2)
|
||||
{}
|
||||
|
||||
template<class U, class V>
|
||||
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
|
||||
: first(::boost::forward<U>(u))
|
||||
, second(::boost::forward<V>(v))
|
||||
{}
|
||||
|
||||
//And now compatibility with std::pair
|
||||
pair(const std::pair<T1, T2>& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
@@ -129,17 +149,20 @@ struct pair
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
//std::pair move constructor
|
||||
template <class D, class S>
|
||||
pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
|
||||
pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
|
||||
template <class D, class S>
|
||||
pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
//piecewise_construct missing
|
||||
//template <class U, class V> pair(pair<U, V>&& p);
|
||||
//template <class... Args1, class... Args2>
|
||||
// pair(piecewise_construct_t, tuple<Args1...> first_args,
|
||||
// tuple<Args2...> second_args);
|
||||
/*
|
||||
//Variadic versions
|
||||
template<class U>
|
||||
@@ -179,14 +202,6 @@ struct pair
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(const pair<D, S>&p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//pair move assignment
|
||||
pair& operator=(BOOST_RV_REF(pair) p)
|
||||
{
|
||||
@@ -196,7 +211,15 @@ struct pair
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
|
||||
pair& operator=(const pair<D, S>&p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
@@ -220,7 +243,7 @@ struct pair
|
||||
}
|
||||
|
||||
//std::pair move assignment
|
||||
pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
|
||||
pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
@@ -228,7 +251,7 @@ struct pair
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
|
||||
pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -62,6 +62,10 @@
|
||||
//!
|
||||
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
|
||||
const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
|
||||
//!
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#define BOOST_CONTAINER_PP_PARAM(U, u) \
|
||||
U && u \
|
||||
@@ -152,7 +156,11 @@ BOOST_PP_CAT(*this->m_p, n) \
|
||||
//!
|
||||
|
||||
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
|
||||
BOOST_PP_CAT(class P, n) = void \
|
||||
BOOST_PP_CAT(class P, n) = void \
|
||||
//!
|
||||
|
||||
#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
|
||||
BOOST_PP_CAT(class P, n) = default_type \
|
||||
//!
|
||||
|
||||
#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#include <boost/container/detail/preprocessor.hpp>
|
||||
#endif
|
||||
@@ -90,43 +90,49 @@ struct rbtree_hook
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//This trait is used to type-pun std::pair because in C++03
|
||||
//compilers std::pair is useless for C++11 features
|
||||
template<class T>
|
||||
struct rbtree_type
|
||||
struct rbtree_internal_data_type
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct rbtree_type< std::pair<T1, T2> >
|
||||
struct rbtree_internal_data_type< std::pair<T1, T2> >
|
||||
{
|
||||
typedef pair<T1, T2> type;
|
||||
};
|
||||
|
||||
|
||||
//The node to be store in the tree
|
||||
template <class T, class VoidPointer>
|
||||
struct rbtree_node
|
||||
: public rbtree_hook<VoidPointer>::type
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
|
||||
//private:
|
||||
//BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
|
||||
|
||||
public:
|
||||
typedef typename rbtree_hook<VoidPointer>::type hook_type;
|
||||
|
||||
typedef T value_type;
|
||||
typedef typename rbtree_type<T>::type internal_type;
|
||||
typedef typename rbtree_internal_data_type<T>::type internal_type;
|
||||
|
||||
typedef rbtree_node<T, VoidPointer> node_type;
|
||||
|
||||
rbtree_node()
|
||||
: m_data()
|
||||
{}
|
||||
private:
|
||||
rbtree_node();
|
||||
rbtree_node (const rbtree_node &);
|
||||
rbtree_node & operator=(const rbtree_node &);
|
||||
|
||||
/*
|
||||
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))
|
||||
: m_data(::boost::move(other.m_data))
|
||||
{}
|
||||
|
||||
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
@@ -152,8 +158,9 @@ struct rbtree_node
|
||||
{ do_assign(other.m_data); return *this; }
|
||||
|
||||
rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
|
||||
{ do_move(other.m_data); return *this; }
|
||||
|
||||
{ do_move_assign(other.m_data); return *this; }
|
||||
*/
|
||||
public:
|
||||
T &get_data()
|
||||
{
|
||||
T* ptr = reinterpret_cast<T*>(&this->m_data);
|
||||
@@ -166,7 +173,7 @@ struct rbtree_node
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// private:
|
||||
internal_type m_data;
|
||||
|
||||
template<class A, class B>
|
||||
@@ -188,22 +195,22 @@ struct rbtree_node
|
||||
{ m_data = v; }
|
||||
|
||||
template<class A, class B>
|
||||
void do_move(std::pair<const A, B> &p)
|
||||
void do_move_assign(std::pair<const A, B> &p)
|
||||
{
|
||||
const_cast<A&>(m_data.first) = boost::move(p.first);
|
||||
m_data.second = boost::move(p.second);
|
||||
const_cast<A&>(m_data.first) = ::boost::move(p.first);
|
||||
m_data.second = ::boost::move(p.second);
|
||||
}
|
||||
|
||||
template<class A, class B>
|
||||
void do_move(pair<const A, B> &p)
|
||||
void do_move_assign(pair<const A, B> &p)
|
||||
{
|
||||
const_cast<A&>(m_data.first) = boost::move(p.first);
|
||||
m_data.second = boost::move(p.second);
|
||||
const_cast<A&>(m_data.first) = ::boost::move(p.first);
|
||||
m_data.second = ::boost::move(p.second);
|
||||
}
|
||||
|
||||
template<class V>
|
||||
void do_move(V &v)
|
||||
{ m_data = boost::move(v); }
|
||||
void do_move_assign(V &v)
|
||||
{ m_data = ::boost::move(v); }
|
||||
};
|
||||
|
||||
}//namespace container_detail {
|
||||
@@ -282,7 +289,7 @@ class rbtree
|
||||
//First recycle a node (this can't throw)
|
||||
try{
|
||||
//This can throw
|
||||
*p = other;
|
||||
p->do_assign(other.m_data);
|
||||
return p;
|
||||
}
|
||||
catch(...){
|
||||
@@ -295,7 +302,7 @@ class rbtree
|
||||
}
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other);
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +326,7 @@ class rbtree
|
||||
//First recycle a node (this can't throw)
|
||||
try{
|
||||
//This can throw
|
||||
*p = boost::move(other);
|
||||
p->do_move_assign(const_cast<Node &>(other).m_data);
|
||||
return p;
|
||||
}
|
||||
catch(...){
|
||||
@@ -332,7 +339,7 @@ class rbtree
|
||||
}
|
||||
}
|
||||
else{
|
||||
return m_holder.create_node(other);
|
||||
return m_holder.create_node(other.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,8 +485,10 @@ class rbtree
|
||||
iterator(){}
|
||||
|
||||
//Pointer like operators
|
||||
reference operator*() const { return this->m_it->get_data(); }
|
||||
pointer operator->() const { return pointer(&this->m_it->get_data()); }
|
||||
reference operator*() const
|
||||
{ return this->m_it->get_data(); }
|
||||
pointer operator->() const
|
||||
{ return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data()); }
|
||||
|
||||
//Increment / Decrement
|
||||
iterator& operator++()
|
||||
@@ -532,9 +541,28 @@ class rbtree
|
||||
}
|
||||
|
||||
rbtree(BOOST_RV_REF(rbtree) x)
|
||||
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
|
||||
: AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
|
||||
{}
|
||||
|
||||
rbtree(const rbtree& x, const allocator_type &a)
|
||||
: AllocHolder(a, x.key_comp())
|
||||
{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
|
||||
: AllocHolder(a, x.key_comp())
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()){
|
||||
this->icont().swap(x.icont());
|
||||
}
|
||||
else{
|
||||
this->icont().clone_from
|
||||
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
|
||||
}
|
||||
}
|
||||
|
||||
~rbtree()
|
||||
{} //AllocHolder clears the tree
|
||||
|
||||
@@ -552,7 +580,7 @@ class rbtree
|
||||
//Transfer all the nodes to a temporary tree
|
||||
//If anything goes wrong, all the nodes will be destroyed
|
||||
//automatically
|
||||
Icont other_tree(boost::move(this->icont()));
|
||||
Icont other_tree(::boost::move(this->icont()));
|
||||
|
||||
//Now recreate the source tree reusing nodes stored by other_tree
|
||||
this->icont().clone_from
|
||||
@@ -578,7 +606,7 @@ class rbtree
|
||||
if(this_alloc == x_alloc){
|
||||
//Destroy and swap pointers
|
||||
this->clear();
|
||||
this->icont() = boost::move(x.icont());
|
||||
this->icont() = ::boost::move(x.icont());
|
||||
//Move allocator if needed
|
||||
this->AllocHolder::move_assign_alloc(x);
|
||||
}
|
||||
@@ -587,7 +615,7 @@ class rbtree
|
||||
//Transfer all the nodes to a temporary tree
|
||||
//If anything goes wrong, all the nodes will be destroyed
|
||||
//automatically
|
||||
Icont other_tree(boost::move(this->icont()));
|
||||
Icont other_tree(::boost::move(this->icont()));
|
||||
|
||||
//Now recreate the source tree reusing nodes stored by other_tree
|
||||
this->icont().clone_from
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -29,6 +29,13 @@ namespace container_detail {
|
||||
|
||||
struct nat{};
|
||||
|
||||
template <typename U>
|
||||
struct LowPriorityConversion
|
||||
{
|
||||
// Convertible from T with user-defined-conversion rank.
|
||||
LowPriorityConversion(const U&) { }
|
||||
};
|
||||
|
||||
//boost::alignment_of yields to 10K lines of preprocessed code, so we
|
||||
//need an alternative
|
||||
template <typename T> struct alignment_of;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -21,13 +21,23 @@
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <typename T>
|
||||
inline T* addressof(T& obj)
|
||||
{
|
||||
return static_cast<T*>(
|
||||
static_cast<void*>(
|
||||
const_cast<char*>(
|
||||
&reinterpret_cast<const char&>(obj)
|
||||
)));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T &max_value(const T &a, const T &b)
|
||||
{ return a > b ? a : b; }
|
||||
@@ -262,6 +272,7 @@ F uninitialized_copy_or_move_alloc
|
||||
return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
|
||||
}
|
||||
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -26,6 +26,11 @@
|
||||
#define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
|
||||
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
|
||||
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <boost/container/detail/flat_tree.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
@@ -209,23 +209,38 @@ class flat_map
|
||||
//! <b>Effects</b>: Copy constructs a flat_map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map(const flat_map<Key,T,Pred,A>& x)
|
||||
flat_map(const flat_map& x)
|
||||
: m_flat_tree(x.m_flat_tree) {}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_map(BOOST_RV_REF(flat_map) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map(const flat_map& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if x.get_allocator() == a, linear otherwise.
|
||||
flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_map<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
|
||||
flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
|
||||
{ m_flat_tree = x.m_flat_tree; return *this; }
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_map.
|
||||
@@ -234,7 +249,7 @@ class flat_map
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_map<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_map) mx)
|
||||
flat_map& operator=(BOOST_RV_REF(flat_map) mx)
|
||||
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
@@ -960,28 +975,43 @@ class flat_multimap
|
||||
//! <b>Effects</b>: Copy constructs a flat_multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap(const flat_multimap<Key,T,Pred,A>& x)
|
||||
flat_multimap(const flat_multimap& x)
|
||||
: m_flat_tree(x.m_flat_tree) { }
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multimap. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
{ }
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_multimap using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap(const flat_multimap& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multimap using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree), a)
|
||||
{ }
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multimap<Key,T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
|
||||
flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x)
|
||||
{ m_flat_tree = x.m_flat_tree; return *this; }
|
||||
|
||||
//! <b>Effects</b>: this->swap(x.get()).
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
flat_multimap<Key,T,Pred,A>& operator=(BOOST_RV_REF(flat_multimap) mx)
|
||||
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx)
|
||||
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -100,14 +100,14 @@ class flat_set
|
||||
typedef typename tree_t::allocator_type allocator_type;
|
||||
typedef typename tree_t::stored_allocator_type stored_allocator_type;
|
||||
|
||||
//! <b>Effects</b>: Defatuls constructs an empty flat_map.
|
||||
//! <b>Effects</b>: Default constructs an empty flat_set.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_set()
|
||||
: m_flat_tree()
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty flat_map using the specified
|
||||
//! <b>Effects</b>: Constructs an empty flat_set using the specified
|
||||
//! comparison object and allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
@@ -116,7 +116,7 @@ class flat_set
|
||||
: m_flat_tree(comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
||||
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
|
||||
//! allocator, and inserts elements from the range [first ,last ).
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
|
||||
@@ -143,31 +143,47 @@ class flat_set
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a map.
|
||||
//! <b>Effects</b>: Copy constructs a set.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_set(const flat_set<T,Pred,A>& x)
|
||||
: m_flat_tree(x.m_flat_tree) {}
|
||||
flat_set(const flat_set& x)
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
|
||||
//! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_set(BOOST_RV_REF(flat_set) mx)
|
||||
: m_flat_tree(boost::move(mx.m_flat_tree))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//! <b>Effects</b>: Copy constructs a set using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_set<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
|
||||
{ m_flat_tree = x.m_flat_tree; return *this; }
|
||||
flat_set(const flat_set& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a set using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
|
||||
flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(mx.m_flat_tree), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_set<T,Pred,A>& operator=(BOOST_RV_REF(flat_set) mx)
|
||||
flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
|
||||
{ m_flat_tree = x.m_flat_tree; return *this; }
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of the previous value of xx.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_set& operator=(BOOST_RV_REF(flat_set) mx)
|
||||
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
@@ -729,7 +745,7 @@ class flat_multiset
|
||||
typedef typename tree_t::allocator_type allocator_type;
|
||||
typedef typename tree_t::stored_allocator_type stored_allocator_type;
|
||||
|
||||
//! <b>Effects</b>: Defatuls constructs an empty flat_map.
|
||||
//! <b>Effects</b>: Default constructs an empty flat_multiset.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit flat_multiset()
|
||||
@@ -761,17 +777,47 @@ class flat_multiset
|
||||
: m_flat_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
|
||||
flat_multiset(const flat_multiset<T,Pred,A>& x)
|
||||
: m_flat_tree(x.m_flat_tree) {}
|
||||
|
||||
flat_multiset(BOOST_RV_REF(flat_multiset) x)
|
||||
: m_flat_tree(boost::move(x.m_flat_tree))
|
||||
//! <b>Effects</b>: Copy constructs a flat_multiset.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multiset(const flat_multiset& x)
|
||||
: m_flat_tree(x.m_flat_tree)
|
||||
{}
|
||||
|
||||
flat_multiset<T,Pred,A>& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
|
||||
//! <b>Effects</b>: Move constructs a flat_multiset. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
flat_multiset(BOOST_RV_REF(flat_multiset) mx)
|
||||
: m_flat_tree(boost::move(mx.m_flat_tree))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a flat_multiset using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multiset(const flat_multiset& x, const allocator_type &a)
|
||||
: m_flat_tree(x.m_flat_tree, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a flat_multiset using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
|
||||
flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a)
|
||||
: m_flat_tree(boost::move(mx.m_flat_tree), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x)
|
||||
{ m_flat_tree = x.m_flat_tree; return *this; }
|
||||
|
||||
flat_multiset<T,Pred,A>& operator=(BOOST_RV_REF(flat_multiset) mx)
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
|
||||
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
|
||||
|
||||
//! <b>Effects</b>: Returns the comparison object out
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -65,30 +65,13 @@ template <class T, class VoidPointer>
|
||||
struct list_node
|
||||
: public list_hook<VoidPointer>::type
|
||||
{
|
||||
private:
|
||||
list_node();
|
||||
list_node(const list_node &);
|
||||
list_node & operator=(const list_node &);
|
||||
|
||||
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
|
||||
|
||||
public:
|
||||
typedef typename list_hook<VoidPointer>::type hook_type;
|
||||
T m_data;
|
||||
};
|
||||
|
||||
@@ -374,6 +357,34 @@ class list
|
||||
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a list using the specified allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||
list(const list& x, const allocator_type &a)
|
||||
: AllocHolder(a)
|
||||
{ this->insert(this->cbegin(), x.begin(), x.end()); }
|
||||
|
||||
//! <b>Effects</b>: Move constructor sing the specified allocator.
|
||||
//! Moves mx's resources to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation or value_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
list(BOOST_RV_REF(list) x, const allocator_type &a)
|
||||
: AllocHolder(a)
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()){
|
||||
this->icont().swap(x.icont());
|
||||
}
|
||||
else{
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||
//! and inserts a copy of the range [first, last) in the list.
|
||||
//!
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -158,7 +158,7 @@ class map
|
||||
: m_tree(first, last, comp, a, true)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and
|
||||
@@ -175,29 +175,52 @@ class map
|
||||
: m_tree(ordered_range, first, last, comp, a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a map.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
map(const map<Key,T,Pred,A>& x)
|
||||
map(const map& x)
|
||||
: m_tree(x.m_tree)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a map. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
map(BOOST_RV_REF(map) x)
|
||||
: m_tree(boost::move(x.m_tree))
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a map using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
map(const map& x, const allocator_type &a)
|
||||
: m_tree(x.m_tree, a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a map using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if x == x.get_allocator(), linear otherwise.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
map(BOOST_RV_REF(map) x, const allocator_type &a)
|
||||
: m_tree(boost::move(x.m_tree), a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
@@ -833,7 +856,7 @@ class multimap
|
||||
: m_tree(comp, a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
|
||||
@@ -848,7 +871,7 @@ class multimap
|
||||
: m_tree(first, last, comp, a, false)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
|
||||
@@ -864,27 +887,48 @@ class multimap
|
||||
: m_tree(ordered_range, first, last, comp, a)
|
||||
{}
|
||||
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
multimap(const multimap<Key,T,Pred,A>& x)
|
||||
multimap(const multimap& x)
|
||||
: m_tree(x.m_tree)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a multimap. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
multimap(BOOST_RV_REF(multimap) x)
|
||||
: m_tree(boost::move(x.m_tree))
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a multimap.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
multimap(const multimap& x, const allocator_type &a)
|
||||
: m_tree(x.m_tree, a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a multimap using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
|
||||
: m_tree(boost::move(x.m_tree), a)
|
||||
{
|
||||
//Allocator type must be std::pair<CONST Key, T>
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -144,16 +144,31 @@ class set
|
||||
|
||||
//! <b>Effects</b>: Move constructs a set. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
set(BOOST_RV_REF(set) x)
|
||||
: m_tree(boost::move(x.m_tree))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//! <b>Effects</b>: Copy constructs a set using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
set(const set& x, const allocator_type &a)
|
||||
: m_tree(x.m_tree, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a set using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
set(BOOST_RV_REF(set) x, const allocator_type &a)
|
||||
: m_tree(boost::move(x.m_tree), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
|
||||
{ m_tree = x.m_tree; return *this; }
|
||||
|
||||
@@ -716,13 +731,30 @@ class multiset
|
||||
|
||||
//! <b>Effects</b>: Move constructs a multiset. Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Construct.
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
multiset(BOOST_RV_REF(multiset) x)
|
||||
: m_tree(boost::move(x.m_tree))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a multiset using the specified allocator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
multiset(const multiset& x, const allocator_type &a)
|
||||
: m_tree(x.m_tree, a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Move constructs a multiset using the specified allocator.
|
||||
//! Constructs *this using x's resources.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x is emptied.
|
||||
multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
|
||||
: m_tree(boost::move(x.m_tree), a)
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Makes *this a copy of x.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear in x.size().
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -65,31 +65,13 @@ template <class T, class VoidPointer>
|
||||
struct slist_node
|
||||
: public slist_hook<VoidPointer>::type
|
||||
{
|
||||
private:
|
||||
slist_node();
|
||||
slist_node(const slist_node &);
|
||||
slist_node & operator=(const slist_node &);
|
||||
|
||||
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
|
||||
|
||||
public:
|
||||
typedef typename slist_hook<VoidPointer>::type hook_type;
|
||||
T m_data;
|
||||
};
|
||||
|
||||
@@ -391,6 +373,34 @@ class slist
|
||||
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a list using the specified allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||
slist(const slist& x, const allocator_type &a)
|
||||
: AllocHolder(a)
|
||||
{ this->insert_after(this->before_begin(), x.begin(), x.end()); }
|
||||
|
||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||
//! Moves x's resources to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation or value_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||
slist(BOOST_RV_REF(slist) x, const allocator_type &a)
|
||||
: AllocHolder(a)
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()){
|
||||
this->icont().swap(x.icont());
|
||||
}
|
||||
else{
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Makes *this contain the same elements as x.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <boost/container/detail/utilities.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -78,10 +78,6 @@ struct smart_ptr_type<T*>
|
||||
{ return ptr;}
|
||||
};
|
||||
|
||||
template<class Ptr>
|
||||
inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
|
||||
{ return smart_ptr_type<Ptr>::get(ptr); }
|
||||
|
||||
template <class C>
|
||||
class clear_on_destroy
|
||||
{
|
||||
@@ -110,13 +106,10 @@ class clear_on_destroy
|
||||
|
||||
template<class VoidPtr>
|
||||
struct node_type_base
|
||||
{/*
|
||||
node_type_base(VoidPtr p)
|
||||
: up(p)
|
||||
{}*/
|
||||
{
|
||||
node_type_base()
|
||||
{}
|
||||
void set_pointer(VoidPtr p)
|
||||
void set_pointer(const VoidPtr &p)
|
||||
{ up = p; }
|
||||
|
||||
VoidPtr up;
|
||||
@@ -126,33 +119,12 @@ template<typename VoidPointer, typename T>
|
||||
struct node_type
|
||||
: public node_type_base<VoidPointer>
|
||||
{
|
||||
node_type()
|
||||
: value()
|
||||
{}
|
||||
|
||||
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<class ...Args>
|
||||
node_type(Args &&...args)
|
||||
: value(boost::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
#else //BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
|
||||
node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
|
||||
: value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
|
||||
{} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif//BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
|
||||
void set_pointer(VoidPointer p)
|
||||
{ node_type_base<VoidPointer>::set_pointer(p); }
|
||||
private:
|
||||
node_type();
|
||||
node_type(const node_type &);
|
||||
node_type & operator=(const node_type &);
|
||||
|
||||
public:
|
||||
T value;
|
||||
};
|
||||
|
||||
@@ -206,17 +178,17 @@ class iterator
|
||||
private:
|
||||
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
|
||||
{
|
||||
return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
return const_node_type_ptr_t(static_cast<const node_type_t*>(container_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
return void_ptr_ptr(static_cast<void_ptr*>(container_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
reference dereference() const
|
||||
@@ -353,35 +325,37 @@ BOOST_JOIN(check_invariant_,__LINE__).touch();
|
||||
|
||||
/// @endcond
|
||||
|
||||
//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
|
||||
//!drop-in replacement implemented as a node container, offering iterator and reference
|
||||
//!stability.
|
||||
//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
|
||||
//! drop-in replacement implemented as a node container, offering iterator and reference
|
||||
//! stability.
|
||||
//!
|
||||
//!More details taken the author's blog: (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" > Introducing stable_vector</a>)
|
||||
//! More details taken the author's blog:
|
||||
//! (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" >
|
||||
//! Introducing stable_vector</a>)
|
||||
//!
|
||||
//!We present stable_vector, a fully STL-compliant stable container that provides
|
||||
//!most of the features of std::vector except element contiguity.
|
||||
//! We present stable_vector, a fully STL-compliant stable container that provides
|
||||
//! most of the features of std::vector except element contiguity.
|
||||
//!
|
||||
//!General properties: stable_vector satisfies all the requirements of a container,
|
||||
//!a reversible container and a sequence and provides all the optional operations
|
||||
//!present in std::vector. Like std::vector, iterators are random access.
|
||||
//!stable_vector does not provide element contiguity; in exchange for this absence,
|
||||
//!the container is stable, i.e. references and iterators to an element of a stable_vector
|
||||
//!remain valid as long as the element is not erased, and an iterator that has been
|
||||
//!assigned the return value of end() always remain valid until the destruction of
|
||||
//!the associated stable_vector.
|
||||
//! General properties: stable_vector satisfies all the requirements of a container,
|
||||
//! a reversible container and a sequence and provides all the optional operations
|
||||
//! present in std::vector. Like std::vector, iterators are random access.
|
||||
//! stable_vector does not provide element contiguity; in exchange for this absence,
|
||||
//! the container is stable, i.e. references and iterators to an element of a stable_vector
|
||||
//! remain valid as long as the element is not erased, and an iterator that has been
|
||||
//! assigned the return value of end() always remain valid until the destruction of
|
||||
//! the associated stable_vector.
|
||||
//!
|
||||
//!Operation complexity: The big-O complexities of stable_vector operations match
|
||||
//!exactly those of std::vector. In general, insertion/deletion is constant time at
|
||||
//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
|
||||
//!does not internally perform any value_type destruction, copy or assignment
|
||||
//!operations other than those exactly corresponding to the insertion of new
|
||||
//!elements or deletion of stored elements, which can sometimes compensate in terms
|
||||
//!of performance for the extra burden of doing more pointer manipulation and an
|
||||
//!additional allocation per element.
|
||||
//! Operation complexity: The big-O complexities of stable_vector operations match
|
||||
//! exactly those of std::vector. In general, insertion/deletion is constant time at
|
||||
//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
|
||||
//! does not internally perform any value_type destruction, copy or assignment
|
||||
//! operations other than those exactly corresponding to the insertion of new
|
||||
//! elements or deletion of stored elements, which can sometimes compensate in terms
|
||||
//! of performance for the extra burden of doing more pointer manipulation and an
|
||||
//! additional allocation per element.
|
||||
//!
|
||||
//!Exception safety: As stable_vector does not internally copy elements around, some
|
||||
//!operations provide stronger exception safety guarantees than in std::vector:
|
||||
//! Exception safety: As stable_vector does not internally copy elements around, some
|
||||
//! operations provide stronger exception safety guarantees than in std::vector:
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
template <class T, class A = std::allocator<T> >
|
||||
#else
|
||||
@@ -524,7 +498,7 @@ class stable_vector
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
explicit stable_vector(const A& al)
|
||||
explicit stable_vector(const allocator_type& al)
|
||||
: internal_data(al),impl(al)
|
||||
{
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
@@ -538,7 +512,7 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
explicit stable_vector(size_type n)
|
||||
: internal_data(A()),impl(A())
|
||||
: internal_data(),impl()
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->resize(n);
|
||||
@@ -553,7 +527,7 @@ class stable_vector
|
||||
//! throws or T's default or copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
stable_vector(size_type n, const T& t, const A& al=A())
|
||||
stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
|
||||
: internal_data(al),impl(al)
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
@@ -570,7 +544,7 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||
template <class InputIterator>
|
||||
stable_vector(InputIterator first,InputIterator last,const A& al=A())
|
||||
stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
|
||||
: internal_data(al),impl(al)
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
@@ -607,6 +581,40 @@ class stable_vector
|
||||
this->priv_swap_members(x);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a stable_vector using the specified allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||
stable_vector(const stable_vector& x, const allocator_type &a)
|
||||
: internal_data(a), impl(a)
|
||||
{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
cod.release();
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||
//! Moves mx's resources to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
|
||||
stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
|
||||
: internal_data(a), impl(a)
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()){
|
||||
this->priv_swap_members(x);
|
||||
}
|
||||
else{
|
||||
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
|
||||
this->insert(this->cbegin(), x.begin(), x.end());
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
cod.release();
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
|
||||
//! and used memory is deallocated.
|
||||
//!
|
||||
@@ -709,7 +717,7 @@ class stable_vector
|
||||
//! <b>Throws</b>: If allocator's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
allocator_type get_allocator()const {return node_alloc();}
|
||||
allocator_type get_allocator()const {return this->node_alloc();}
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the internal allocator.
|
||||
//!
|
||||
@@ -1137,7 +1145,7 @@ class stable_vector
|
||||
void emplace_back(Args &&...args)
|
||||
{
|
||||
typedef emplace_functor<Args...> EmplaceFunctor;
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
|
||||
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
|
||||
}
|
||||
@@ -1157,7 +1165,7 @@ class stable_vector
|
||||
//Just call more general insert(pos, size, value) and return iterator
|
||||
size_type pos_n = position - cbegin();
|
||||
typedef emplace_functor<Args...> EmplaceFunctor;
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
|
||||
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
|
||||
return iterator(this->begin() + pos_n);
|
||||
@@ -1172,7 +1180,7 @@ class stable_vector
|
||||
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
|
||||
EmplaceFunctor; \
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
|
||||
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
|
||||
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
|
||||
BOOST_PP_RPAREN_IF(n); \
|
||||
@@ -1186,7 +1194,7 @@ class stable_vector
|
||||
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
|
||||
EmplaceFunctor; \
|
||||
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator; \
|
||||
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
|
||||
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
|
||||
BOOST_PP_RPAREN_IF(n); \
|
||||
@@ -1482,12 +1490,12 @@ class stable_vector
|
||||
|
||||
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
|
||||
{
|
||||
return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
|
||||
return node_type_base_ptr_t(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p)));
|
||||
}
|
||||
|
||||
static value_type& value(const void_ptr &p)
|
||||
@@ -1529,7 +1537,9 @@ class stable_vector
|
||||
{
|
||||
node_type_ptr_t p = this->allocate_one();
|
||||
try{
|
||||
boost::container::construct_in_place(this->node_alloc(), &*p, it);
|
||||
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), it);
|
||||
//This does not throw
|
||||
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
|
||||
p->set_pointer(up);
|
||||
}
|
||||
catch(...){
|
||||
@@ -1621,7 +1631,9 @@ class stable_vector
|
||||
p = mem.front();
|
||||
mem.pop_front();
|
||||
//This can throw
|
||||
boost::container::construct_in_place(this->node_alloc(), &*p, first);
|
||||
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
|
||||
//This does not throw
|
||||
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
|
||||
p->set_pointer(void_ptr_ptr(&it[i]));
|
||||
++first;
|
||||
it[i] = p;
|
||||
@@ -1650,7 +1662,9 @@ class stable_vector
|
||||
break;
|
||||
}
|
||||
//This can throw
|
||||
boost::container::construct_in_place(this->node_alloc(), &*p, first);
|
||||
boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
|
||||
//This does not throw
|
||||
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
|
||||
p->set_pointer(void_ptr_ptr(&it[i]));
|
||||
++first;
|
||||
it[i]=p;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -43,7 +43,7 @@
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/allocation_type.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
@@ -620,12 +620,12 @@ class basic_string
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
|
||||
//! <b>Throws</b>: If allocator_type's default constructor throws.
|
||||
basic_string(const basic_string& s)
|
||||
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
|
||||
{ this->priv_range_initialize(s.begin(), s.end()); }
|
||||
|
||||
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
|
||||
//! <b>Effects</b>: Move constructor. Moves s's resources to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
||||
//!
|
||||
@@ -634,6 +634,32 @@ class basic_string
|
||||
: base_t(boost::move((base_t&)s))
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation throws.
|
||||
basic_string(const basic_string& s, const allocator_type &a)
|
||||
: base_t(a)
|
||||
{ this->priv_range_initialize(s.begin(), s.end()); }
|
||||
|
||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||
//! Moves s's resources to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == s.get_allocator(), linear otherwise.
|
||||
basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
|
||||
: base_t(a)
|
||||
{
|
||||
if(a == this->alloc()){
|
||||
this->swap_data(s);
|
||||
}
|
||||
else{
|
||||
this->priv_range_initialize(s.begin(), s.end());
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
|
||||
//! and is initialized by a specific number of characters of the s string.
|
||||
basic_string(const basic_string& s, size_type pos, size_type n = npos,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/algorithms.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/allocator/allocator_traits.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/move/move_helpers.hpp>
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/advanced_insert_int.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -540,6 +541,40 @@ class vector : private container_detail::vector_alloc_holder<A>
|
||||
: base_t(boost::move(mx.alloc()))
|
||||
{ this->swap_members(mx); }
|
||||
|
||||
//! <b>Effects</b>: Copy constructs a vector using the specified allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: x == *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation
|
||||
//! throws or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||
vector(const vector &x, const allocator_type &a)
|
||||
: base_t(a)
|
||||
{
|
||||
this->assign( container_detail::to_raw_pointer(x.members_.m_start)
|
||||
, container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||
//! Moves mx's resources to *this if a == allocator_type().
|
||||
//! Otherwise copies values from x to *this.
|
||||
//!
|
||||
//! <b>Throws</b>: If allocation or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
|
||||
vector(BOOST_RV_REF(vector) mx, const allocator_type &a)
|
||||
: base_t(a)
|
||||
{
|
||||
if(mx.alloc() == a){
|
||||
this->swap_members(mx);
|
||||
}
|
||||
else{
|
||||
this->assign( container_detail::to_raw_pointer(mx.members_.m_start)
|
||||
, container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size));
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
|
||||
//! and inserts a copy of the range [first, last) in the vector.
|
||||
//!
|
||||
@@ -1428,6 +1463,87 @@ class vector : private container_detail::vector_alloc_holder<A>
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template<class BiDirIt>
|
||||
void insert_at_ordered_positions(const size_type *positions, size_type element_count, BiDirIt end)
|
||||
{
|
||||
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 = positions[insertions_left - 1];
|
||||
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 = shift_range(pos, next_pos, this->size(), insertions_left);
|
||||
if(new_hole_size > 0){
|
||||
//The hole was reduced by 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, *(--end));
|
||||
--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 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] = *(--end);
|
||||
}
|
||||
--insertions_left;
|
||||
hole_size = new_hole_size;
|
||||
next_pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
size_type 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;
|
||||
if((last_pos + shift_count) < limit_pos){
|
||||
//All inside
|
||||
boost::move_backward(begin_ptr + first_pos, begin_ptr + last_pos, begin_ptr + last_pos + shift_count);
|
||||
}
|
||||
else if((first_pos + shift_count) >= limit_pos){
|
||||
//All outside
|
||||
::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;
|
||||
}
|
||||
else{
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), begin_ptr + limit_pos - shift_count, begin_ptr + last_pos, begin_ptr + limit_pos);
|
||||
boost::move_backward(begin_ptr + first_pos, begin_ptr + limit_pos - shift_count, begin_ptr + limit_pos + shift_count);
|
||||
}
|
||||
return hole_size;
|
||||
}
|
||||
|
||||
private:
|
||||
void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
|
||||
{
|
||||
//n can't be 0, because there is nothing to do in that case
|
||||
|
Reference in New Issue
Block a user