Introducing allocator_traits and pointer_traits changes into several libraries.

[SVN r76106]
This commit is contained in:
Ion Gaztañaga
2011-12-22 20:08:24 +00:00
parent 5247083184
commit 935a534713
41 changed files with 4304 additions and 2448 deletions

View File

@@ -0,0 +1,381 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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/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_DEFAULT(boost::container::container_detail::, Alloc,
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const value_type>::type)
const_pointer;
//reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
reference, value_type&)
reference;
//const_reference
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
const_reference, const value_type&)
const_reference;
//void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<void>::type)
void_pointer;
//const_void_pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const void>::type)
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)

View File

@@ -0,0 +1,77 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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)

View File

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

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
#define BOOST_CONTAINERS_CONTAINERS_FWD_HPP
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -26,7 +26,7 @@ namespace intrusive{
//Create namespace to avoid compilation errors
}}
namespace boost{ namespace container{ namespace containers_detail{
namespace boost{ namespace container{ namespace container_detail{
namespace bi = boost::intrusive;
@@ -195,4 +195,4 @@ struct dummy
}} //namespace boost { namespace container {
#endif //#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/container/detail/type_traits.hpp>
@@ -31,7 +31,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class size_type>
struct hdr_offset_holder_t
@@ -221,7 +221,7 @@ class private_adaptive_node_pool_impl
//!Returns the segment manager. Never throws
segment_manager_base_type* get_segment_manager_base()const
{ return containers_detail::get_pointer(mp_segment_mngr_base); }
{ return container_detail::to_raw_pointer(mp_segment_mngr_base); }
//!Allocates array of count elements. Can throw
void *allocate_node()
@@ -348,7 +348,7 @@ class private_adaptive_node_pool_impl
{
block_iterator block_it(m_block_multiset.end());
while(n--){
void *pElem = containers_detail::get_pointer(chain.front());
void *pElem = container_detail::to_raw_pointer(chain.front());
chain.pop_front();
priv_invariants();
block_info_t *block_info = this->priv_block_from_node(pElem);
@@ -434,7 +434,7 @@ class private_adaptive_node_pool_impl
(void)free_nodes;
BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
BOOST_ASSERT(0 == to_deallocate->hdr_offset);
hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(containers_detail::get_pointer(to_deallocate));
hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
}
@@ -557,7 +557,7 @@ class private_adaptive_node_pool_impl
(mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
if(!mem_address) throw std::bad_alloc();
++m_totally_free_blocks;
block_info_t *c_info = new(mem_address)block_info_t;
block_info_t *c_info = new(mem_address)block_info_t();
m_block_multiset.insert(m_block_multiset.end(), *c_info);
mem_address += HdrSize;
@@ -587,7 +587,7 @@ class private_adaptive_node_pool_impl
//First initialize header information on the last subblock
char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
block_info_t *c_info = new(hdr_addr)block_info_t;
block_info_t *c_info = new(hdr_addr)block_info_t();
//Some structural checks
BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
static_cast<void*>(c_info));
@@ -622,8 +622,8 @@ class private_adaptive_node_pool_impl
{ return priv_alloc_block(n, IsAlignOnly()); }
private:
typedef typename boost::pointer_to_other
<void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
typedef typename boost::intrusive::pointer_traits
<void_pointer>::template rebind_pointer<segment_manager_base_type>::type segment_mngr_base_ptr_t;
const size_type m_max_free_blocks;
const size_type m_real_node_size;
//Round the size to a power of two value.
@@ -639,7 +639,7 @@ class private_adaptive_node_pool_impl
size_type m_totally_free_blocks; //Free blocks
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
#define BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -17,54 +17,58 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/move/move.hpp>
#include <iterator> //std::iterator_traits
#include <new> //placement new
#include <boost/assert.hpp>
namespace boost { namespace container { namespace containers_detail {
namespace boost { namespace container { namespace container_detail {
//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
template<class T, class Iterator>
template<class Iterator>
struct advanced_insert_aux_int
{
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
virtual void copy_all_to(Iterator p) = 0;
virtual void uninitialized_copy_all_to(Iterator p) = 0;
virtual void copy_remaining_to(Iterator p) = 0;
virtual void uninitialized_copy_remaining_to(Iterator p) = 0;
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
virtual ~advanced_insert_aux_int() {}
};
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class FwdIt, class Iterator>
template<class A, class FwdIt, class Iterator>
struct advanced_insert_aux_proxy
: public advanced_insert_aux_int<T, Iterator>
: public advanced_insert_aux_int<Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
advanced_insert_aux_proxy(FwdIt first, FwdIt last)
: first_(first), last_(last)
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;
advanced_insert_aux_proxy(A& a, FwdIt first, FwdIt last)
: a_(a), first_(first), last_(last)
{}
virtual ~advanced_insert_aux_proxy()
{}
virtual void copy_all_to(Iterator p)
virtual void copy_remaining_to(Iterator p)
{ ::boost::copy_or_move(first_, last_, p); }
virtual void uninitialized_copy_all_to(Iterator p)
{ ::boost::uninitialized_copy_or_move(first_, last_, p); }
virtual void uninitialized_copy_remaining_to(Iterator p)
{ ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
FwdIt mid = first_;
std::advance(mid, division_count);
if(first_n){
::boost::uninitialized_copy_or_move(first_, mid, pos);
::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
first_ = mid;
}
else{
::boost::uninitialized_copy_or_move(mid, last_, pos);
::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
last_ = mid;
}
}
@@ -82,53 +86,38 @@ struct advanced_insert_aux_proxy
last_ = mid;
}
}
A &a_;
FwdIt first_, last_;
};
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class Iterator, class SizeType>
//This class template will adapt default construction insertions to advanced_insert_aux_int
template<class A, class Iterator>
struct default_construct_aux_proxy
: public advanced_insert_aux_int<T, Iterator>
: public advanced_insert_aux_int<Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
default_construct_aux_proxy(SizeType count)
: count_(count)
{}
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;
void uninitialized_copy_impl(Iterator p, const SizeType n)
{
BOOST_ASSERT(n <= count_);
Iterator orig_p = p;
SizeType i = 0;
try{
for(; i < n; ++i, ++p){
new(containers_detail::get_pointer(&*p))T();
}
}
catch(...){
while(i--){
containers_detail::get_pointer(&*orig_p++)->~T();
}
throw;
}
count_ -= n;
}
default_construct_aux_proxy(A &a, size_type count)
: a_(a), count_(count)
{}
virtual ~default_construct_aux_proxy()
{}
virtual void copy_all_to(Iterator)
virtual void copy_remaining_to(Iterator)
{ //This should never be called with any count
BOOST_ASSERT(count_ == 0);
}
virtual void uninitialized_copy_all_to(Iterator p)
{ this->uninitialized_copy_impl(p, count_); }
virtual void uninitialized_copy_remaining_to(Iterator p)
{ this->priv_uninitialized_copy(p, count_); }
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
{
SizeType new_count;
size_type new_count;
if(first_n){
new_count = division_count;
}
@@ -136,13 +125,13 @@ struct default_construct_aux_proxy
BOOST_ASSERT(difference_type(count_)>= division_count);
new_count = count_ - division_count;
}
this->uninitialized_copy_impl(pos, new_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);
SizeType new_count;
size_type new_count;
if(first_n){
new_count = division_count;
}
@@ -155,12 +144,32 @@ struct default_construct_aux_proxy
(void)new_count;
}
SizeType count_;
private:
void priv_uninitialized_copy(Iterator p, const size_type n)
{
BOOST_ASSERT(n <= 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));
}
}
catch(...){
while(i--){
alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
}
throw;
}
count_ -= n;
}
A &a_;
size_type count_;
};
}}} //namespace boost { namespace container { namespace containers_detail {
}}} //namespace boost { namespace container { namespace container_detail {
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
#include <boost/container/detail/stored_ref.hpp>
@@ -169,217 +178,251 @@ struct default_construct_aux_proxy
//#include <iostream> //For debugging purposes
namespace boost {
namespace container {
namespace containers_detail {
namespace container {
namespace container_detail {
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class Iterator, class ...Args>
struct advanced_insert_aux_emplace
: public advanced_insert_aux_int<T, Iterator>
//This class template will adapt emplace construction insertions of movable types
//to advanced_insert_aux_int
template<class A, class Iterator, class ...Args>
struct advanced_insert_aux_non_movable_emplace
: public advanced_insert_aux_int<Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
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;
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
explicit advanced_insert_aux_emplace(Args&&... args)
: args_(args...)
explicit advanced_insert_aux_non_movable_emplace(A &a, Args&&... args)
: a_(a)
, args_(args...)
, used_(false)
{}
~advanced_insert_aux_emplace()
~advanced_insert_aux_non_movable_emplace()
{}
virtual void copy_all_to(Iterator p)
{ this->priv_copy_all_to(index_tuple_t(), p); }
virtual void copy_remaining_to(Iterator)
//This code can't be called since value_type is not movable or copyable
{ BOOST_ASSERT(false); }
virtual void uninitialized_copy_all_to(Iterator p)
{ this->priv_uninitialized_copy_all_to(index_tuple_t(), p); }
virtual void uninitialized_copy_remaining_to(Iterator p)
{ this->priv_uninitialized_copy_remaining_to(index_tuple_t(), p); }
virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{ this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{ this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
virtual void copy_some_and_update(Iterator, difference_type, bool )
//This code can't be called since value_type is not movable or copyable
{ BOOST_ASSERT(false); }
private:
template<int ...IdxPack>
void priv_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!used_){
*p = boost::move(T (::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...));
used_ = true;
}
}
template<int ...IdxPack>
void priv_uninitialized_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!used_){
new(containers_detail::get_pointer(&*p))T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...);
used_ = true;
}
}
template<int ...IdxPack>
void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
{
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
new(containers_detail::get_pointer(&*p))T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...);
alloc_traits::construct( a_
, container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail::
stored_ref<Args>::forward(get<IdxPack>(args_))...
);
used_ = true;
}
}
}
template<int ...IdxPack>
void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
{
if(!used_){
alloc_traits::construct( a_
, container_detail::to_raw_pointer(&*p)
, ::boost::container::container_detail::
stored_ref<Args>::forward(get<IdxPack>(args_))...
);
used_ = true;
}
}
protected:
A &a_;
tuple<Args&...> args_;
bool used_;
};
//This class template will adapt emplace construction insertions of movable types
//to advanced_insert_aux_int
template<class A, class Iterator, class ...Args>
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 typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::index_tuple_t index_tuple_t;
explicit advanced_insert_aux_emplace(A &a, Args&&... args)
: base_t(a, boost::forward<Args>(args)...)
{}
~advanced_insert_aux_emplace()
{}
//Override only needed functions
virtual void copy_remaining_to(Iterator p)
{ this->priv_copy_remaining_to(index_tuple_t(), p); }
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{ this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
private:
template<int ...IdxPack>
void priv_copy_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_))...));
this->used_ = true;
}
}
template<int ...IdxPack>
void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
{
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
*p = boost::move(T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...));
used_ = true;
if(!this->used_){
*p = boost::move(value_type(
::boost::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...));
this->used_ = true;
}
}
}
tuple<Args&...> args_;
bool used_;
};
}}} //namespace boost { namespace container { namespace containers_detail {
}}} //namespace boost { namespace container { namespace container_detail {
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/value_init.hpp>
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
//This class template will adapt each FwIt types to advanced_insert_aux_int
template<class T, class Iterator>
struct advanced_insert_aux_emplace
: public advanced_insert_aux_int<T, Iterator>
{
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
advanced_insert_aux_emplace()
: used_(false)
{}
~advanced_insert_aux_emplace()
{}
virtual void copy_all_to(Iterator p)
{
if(!used_){
value_init<T>v;
*p = boost::move(v.m_t);
used_ = true;
}
}
virtual void uninitialized_copy_all_to(Iterator p)
{
if(!used_){
new(containers_detail::get_pointer(&*p))T();
used_ = true;
}
}
virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
new(containers_detail::get_pointer(&*p))T();
used_ = true;
}
}
}
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
{
BOOST_ASSERT(division_count <=1);
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
if(!used_){
value_init<T>v;
*p = boost::move(v.m_t);
used_ = true;
}
}
}
private:
bool used_;
};
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T, class Iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
: public advanced_insert_aux_int<T, Iterator> \
{ \
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type; \
\
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
: used_(false), BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
\
virtual void copy_all_to(Iterator p) \
{ \
if(!used_){ \
T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
*p = boost::move(v); \
used_ = true; \
} \
} \
\
virtual void uninitialized_copy_all_to(Iterator p) \
{ \
if(!used_){ \
new(containers_detail::get_pointer(&*p))T \
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
used_ = true; \
} \
} \
\
virtual void uninitialized_copy_some_and_update \
(Iterator p, difference_type division_count, bool first_n) \
{ \
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \
new(containers_detail::get_pointer(&*p))T \
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
used_ = true; \
} \
} \
} \
\
virtual void copy_some_and_update \
(Iterator p, difference_type division_count, bool first_n) \
{ \
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \
T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
*p = boost::move(v); \
used_ = true; \
} \
} \
} \
\
bool used_; \
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
}; \
#define BOOST_PP_LOCAL_MACRO(n) \
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \
: 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; \
\
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \
( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
: a_(a) \
, used_(false) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_INIT, _) \
{} \
\
virtual void copy_remaining_to(Iterator) \
{ BOOST_ASSERT(false); } \
\
virtual void uninitialized_copy_remaining_to(Iterator p) \
{ \
if(!used_){ \
alloc_traits::construct \
( a_ \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
used_ = true; \
} \
} \
\
virtual void uninitialized_copy_some_and_update \
(Iterator p, difference_type division_count, bool first_n) \
{ \
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!used_){ \
alloc_traits::construct \
( a_ \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
used_ = true; \
} \
} \
} \
\
virtual void copy_some_and_update(Iterator, difference_type, bool) \
{ BOOST_ASSERT(false); } \
\
A &a_; \
bool used_; \
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
\
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
: BOOST_PP_CAT(BOOST_PP_CAT( \
advanced_insert_aux_non_movable_emplace, n), arg) \
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > \
{ \
typedef BOOST_PP_CAT(BOOST_PP_CAT( \
advanced_insert_aux_non_movable_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; \
\
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
: base_t(a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
{} \
\
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); \
this->used_ = true; \
} \
} \
\
virtual void copy_some_and_update \
(Iterator p, difference_type division_count, bool first_n) \
{ \
BOOST_ASSERT(division_count <=1); \
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
if(!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); \
this->used_ = true; \
} \
} \
} \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
}}} //namespace boost { namespace container { namespace containers_detail {
}}} //namespace boost { namespace container { namespace container_detail {
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP

View File

@@ -10,8 +10,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
#define BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -23,7 +23,6 @@
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/get_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
@@ -33,56 +32,25 @@
#include <cstring>
namespace boost {
namespace container {
namespace container {
#if defined(BOOST_NO_RVALUE_REFERENCES)
template<class T>
struct has_own_construct_from_it
template<class A, class T, class InpIt>
inline void construct_in_place(A &a, T* dest, InpIt source)
{ boost::container::allocator_traits<A>::construct(a, dest, *source); }
//#endif
template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, default_construct_iterator<U, D>)
{
static const bool value = false;
};
namespace containers_detail {
template<class T, class InpIt>
inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::true_)
{
T::construct(dest, *source);
boost::container::allocator_traits<A>::construct(a, dest);
}
template<class T, class InpIt>
inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::false_)
template<class A, class T, class U, class EF, class D>
inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei)
{
new((void*)dest)T(*source);
ei.construct_in_place(a, dest);
}
} //namespace containers_detail {
template<class T, class InpIt>
inline void construct_in_place(T* dest, InpIt source)
{
typedef containers_detail::bool_<has_own_construct_from_it<T>::value> boolean_t;
containers_detail::construct_in_place_impl(dest, source, boolean_t());
}
#else
template<class T, class InpIt>
inline void construct_in_place(T* dest, InpIt source)
{ ::new((void*)dest)T(*source); }
#endif
template<class T, class U, class D>
inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
{
::new((void*)dest)T();
}
template<class T, class U, class E, class D>
inline void construct_in_place(T *dest, emplace_iterator<U, E, D> ei)
{
ei.construct_in_place(dest);
}
/*
template<class InIt, class OutIt>
struct optimize_assign
{
@@ -118,7 +86,7 @@ struct optimize_copy<T*, T*>
{};
template<class InIt, class OutIt> inline
OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, containers_detail::bool_<false>)
OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, container_detail::bool_<false>)
{
for (; length--; ++dest, ++first)
*dest = *first;
@@ -126,7 +94,7 @@ OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::differenc
}
template<class T> inline
T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, container_detail::bool_<true>)
{
std::size_t size = length*sizeof(T);
return (static_cast<T*>(std::memmove(dest, first, size))) + size;
@@ -136,14 +104,14 @@ template<class InIt, class OutIt> inline
OutIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
{
const bool do_optimized_assign = optimize_assign<InIt, OutIt>::value;
return copy_n_dispatch(first, length, dest, containers_detail::bool_<do_optimized_assign>());
return copy_n_dispatch(first, length, dest, container_detail::bool_<do_optimized_assign>());
}
template<class InIt, class FwdIt> inline
FwdIt uninitialized_copy_n_dispatch
(InIt first,
typename std::iterator_traits<InIt>::difference_type count,
FwdIt dest, containers_detail::bool_<false>)
FwdIt dest, container_detail::bool_<false>)
{
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
//Save initial destination position
@@ -153,14 +121,14 @@ FwdIt uninitialized_copy_n_dispatch
BOOST_TRY{
//Try to build objects
for (; --new_count; ++dest, ++first){
construct_in_place(containers_detail::get_pointer(&*dest), first);
construct_in_place(container_detail::to_raw_pointer(&*dest), first);
}
}
BOOST_CATCH(...){
//Call destructors
new_count = count - new_count;
for (; new_count--; ++dest_init){
containers_detail::get_pointer(&*dest_init)->~value_type();
container_detail::to_raw_pointer(&*dest_init)->~value_type();
}
BOOST_RETHROW
}
@@ -168,7 +136,7 @@ FwdIt uninitialized_copy_n_dispatch
return dest;
}
template<class T> inline
T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, container_detail::bool_<true>)
{
std::size_t size = length*sizeof(T);
return (static_cast<T*>(std::memmove(dest, first, size))) + size;
@@ -181,7 +149,7 @@ FwdIt uninitialized_copy_n
FwdIt dest)
{
const bool do_optimized_copy = optimize_copy<InIt, FwdIt>::value;
return uninitialized_copy_n_dispatch(first, count, dest, containers_detail::bool_<do_optimized_copy>());
return uninitialized_copy_n_dispatch(first, count, dest, container_detail::bool_<do_optimized_copy>());
}
// uninitialized_copy_copy
@@ -199,17 +167,17 @@ FwdIt uninitialized_copy_copy
}
BOOST_CATCH(...){
for(;result != mid; ++result){
containers_detail::get_pointer(&*result)->~value_type();
container_detail::to_raw_pointer(&*result)->~value_type();
}
BOOST_RETHROW
}
BOOST_CATCH_END
}
*/
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP

View File

@@ -8,8 +8,8 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
#define BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -51,4 +51,4 @@ static const allocation_type zero_memory = (allocation_type)zero_memory_v
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
#endif //BOOST_CONTAINER_ALLOCATION_TYPE_HPP

View File

@@ -7,15 +7,15 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
#define BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
#include <boost/config.hpp>
#endif //BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
#endif //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
#ifdef BOOST_MSVC
#ifndef _CRT_SECURE_NO_DEPRECATE
#define BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
#define BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning (push)

View File

@@ -9,8 +9,8 @@
//////////////////////////////////////////////////////////////////////////////
#if defined BOOST_MSVC
#pragma warning (pop)
#ifdef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
#undef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
#ifdef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
#undef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
#undef _CRT_SECURE_NO_DEPRECATE
#endif
#endif

View File

@@ -10,8 +10,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
#define BOOST_CONTAINERS_DESTROYERS_HPP
#ifndef BOOST_CONTAINER_DESTROYERS_HPP
#define BOOST_CONTAINER_DESTROYERS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -21,18 +21,20 @@
#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>
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an array of objects using a STL allocator.
template <class Allocator>
struct scoped_array_deallocator
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::size_type size_type;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
scoped_array_deallocator(pointer p, Allocator& a, size_type length)
: m_ptr(p), m_alloc(a), m_length(length) {}
@@ -52,8 +54,9 @@ struct scoped_array_deallocator
template <class Allocator>
struct null_scoped_array_deallocator
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::size_type size_type;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_array_deallocator(pointer, Allocator&, size_type)
{}
@@ -68,15 +71,13 @@ struct null_scoped_array_deallocator
template <class Allocator>
struct scoped_destructor_n
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::value_type value_type;
typedef typename Allocator::size_type size_type;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::value_type value_type;
typedef typename AllocTraits::size_type size_type;
pointer m_p;
size_type m_n;
scoped_destructor_n(pointer p, size_type n)
: m_p(p), m_n(n)
scoped_destructor_n(pointer p, Allocator& a, size_type n)
: m_p(p), m_a(a), m_n(n)
{}
void release()
@@ -88,10 +89,15 @@ struct scoped_destructor_n
~scoped_destructor_n()
{
if(!m_p) return;
value_type *raw_ptr = containers_detail::get_pointer(m_p);
value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
for(size_type i = 0; i < m_n; ++i, ++raw_ptr)
raw_ptr->~value_type();
AllocTraits::destroy(m_a, raw_ptr);
}
private:
pointer m_p;
Allocator & m_a;
size_type m_n;
};
//!A deleter for scoped_ptr that destroys
@@ -99,10 +105,11 @@ struct scoped_destructor_n
template <class Allocator>
struct null_scoped_destructor_n
{
typedef typename Allocator::pointer pointer;
typedef typename Allocator::size_type size_type;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_destructor_n(pointer, size_type)
null_scoped_destructor_n(pointer, Allocator&, size_type)
{}
void increment_size(size_type)
@@ -112,43 +119,45 @@ struct null_scoped_destructor_n
{}
};
template <class A>
template <class Allocator>
class allocator_destroyer
{
typedef typename A::value_type value_type;
typedef containers_detail::integral_constant<unsigned,
boost::container::containers_detail::
version<A>::value> alloc_version;
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
typedef boost::container::allocator_traits<Allocator> AllocTraits;
typedef typename AllocTraits::value_type value_type;
typedef typename AllocTraits::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<Allocator>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private:
A & a_;
Allocator & a_;
private:
void priv_deallocate(const typename A::pointer &p, allocator_v1)
{ a_.deallocate(p, 1); }
void priv_deallocate(const pointer &p, allocator_v1)
{ AllocTraits::deallocate(a_,p, 1); }
void priv_deallocate(const typename A::pointer &p, allocator_v2)
void priv_deallocate(const pointer &p, allocator_v2)
{ a_.deallocate_one(p); }
public:
allocator_destroyer(A &a)
: a_(a)
allocator_destroyer(Allocator &a)
: a_(a)
{}
void operator()(const typename A::pointer &p)
{
containers_detail::get_pointer(p)->~value_type();
void operator()(const pointer &p)
{
AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
priv_deallocate(p, alloc_version());
}
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
#endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP

View File

@@ -8,8 +8,8 @@
//
////////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_FLAT_TREE_HPP
#define BOOST_CONTAINERS_FLAT_TREE_HPP
#ifndef BOOST_CONTAINER_FLAT_TREE_HPP
#define BOOST_CONTAINER_FLAT_TREE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -37,7 +37,7 @@ namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class Compare, class Value, class KeyOfValue>
class flat_tree_value_compare
@@ -47,6 +47,10 @@ class flat_tree_value_compare
typedef Value second_argument_type;
typedef bool return_type;
public:
flat_tree_value_compare()
: Compare()
{}
flat_tree_value_compare(const Compare &pred)
: Compare(pred)
{}
@@ -67,9 +71,9 @@ class flat_tree_value_compare
template<class Pointer>
struct get_flat_tree_iterators
{
typedef typename containers_detail::
typedef typename container_detail::
vector_iterator<Pointer> iterator;
typedef typename containers_detail::
typedef typename container_detail::
vector_const_iterator<Pointer> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -90,23 +94,29 @@ class flat_tree
//Inherit from value_compare to do EBO
: public value_compare
{
private:
BOOST_COPYABLE_AND_MOVABLE(Data)
public:
Data()
: value_compare(), m_vect()
{}
Data(const Data &d)
: value_compare(d), m_vect(d.m_vect)
{}
Data(const Compare &comp,
const vector_t &vect)
: value_compare(comp), m_vect(vect){}
Data(const value_compare &comp,
const vector_t &vect)
: value_compare(comp), m_vect(vect){}
Data(BOOST_RV_REF(Data) d)
: value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
{}
Data(const Compare &comp)
: value_compare(comp), m_vect()
{}
Data(const Compare &comp,
const allocator_t &alloc)
: value_compare(comp), m_vect(alloc){}
: value_compare(comp), m_vect(alloc)
{}
Data& operator=(BOOST_COPY_ASSIGN_REF(Data) d)
{
@@ -122,6 +132,13 @@ class flat_tree
return *this;
}
void swap(Data &d)
{
value_compare& mycomp = *this, & othercomp = d;
container_detail::do_swap(mycomp, othercomp);
this->m_vect.swap(d.m_vect);
}
vector_t m_vect;
};
@@ -138,23 +155,30 @@ class flat_tree
typedef Key key_type;
typedef Compare key_compare;
typedef typename vector_t::allocator_type allocator_type;
typedef allocator_type stored_allocator_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename vector_t::size_type size_type;
typedef typename vector_t::difference_type difference_type;
typedef typename vector_t::iterator iterator;
typedef typename vector_t::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef typename vector_t::reverse_iterator reverse_iterator;
typedef typename vector_t::const_reverse_iterator const_reverse_iterator;
// allocation/deallocation
flat_tree(const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
//!Standard extension
typedef allocator_type stored_allocator_type;
flat_tree()
: m_data()
{ }
explicit flat_tree(const Compare& comp)
: m_data(comp)
{ }
flat_tree(const Compare& comp, const allocator_type& a)
: m_data(comp, a)
{ }
flat_tree(const flat_tree& x)
: m_data(x.m_data, x.m_data.m_vect)
: m_data(x.m_data)
{ }
flat_tree(BOOST_RV_REF(flat_tree) x)
@@ -237,14 +261,7 @@ class flat_tree
{ return this->m_data.m_vect.max_size(); }
void swap(flat_tree& other)
{
value_compare& mycomp = this->m_data;
value_compare& othercomp = other.m_data;
containers_detail::do_swap(mycomp, othercomp);
vector_t & myvect = this->m_data.m_vect;
vector_t & othervect = other.m_data.m_vect;
myvect.swap(othervect);
}
{ this->m_data.swap(other.m_data); }
public:
// insert/erase
@@ -332,7 +349,7 @@ class flat_tree
priv_insert_equal(first, last, ItCat());
}
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template <class... Args>
iterator emplace_unique(Args&&... args)
@@ -377,100 +394,69 @@ class flat_tree
return priv_insert_commit(data, boost::move(val));
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
iterator emplace_unique()
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
insert_commit_data data;
std::pair<iterator,bool> ret =
priv_insert_unique_prepare(val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::move(val));
}
return ret.first;
}
iterator emplace_hint_unique(const_iterator hint)
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
insert_commit_data data;
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
if(ret.second){
ret.first = priv_insert_commit(data, boost::move(val));
}
return ret.first;
}
iterator emplace_equal()
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
iterator i = this->upper_bound(KeyOfValue()(val));
i = this->m_data.m_vect.insert(i, boost::move(val));
return i;
}
iterator emplace_hint_equal(const_iterator hint)
{
containers_detail::value_init<value_type> vval;
value_type &val = vval.m_t;
insert_commit_data data;
priv_insert_equal_prepare(hint, val, data);
return priv_insert_commit(data, boost::move(val));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \
insert_commit_data data; \
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
if(ret.second){ \
ret.first = priv_insert_commit(data, boost::move(val)); \
ret.first = priv_insert_commit(data, boost::move(val)); \
} \
return ret.first; \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint_unique(const_iterator hint, \
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_unique(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \
insert_commit_data data; \
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
if(ret.second){ \
ret.first = priv_insert_commit(data, boost::move(val)); \
ret.first = priv_insert_commit(data, boost::move(val)); \
} \
return ret.first; \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \
iterator i = this->upper_bound(KeyOfValue()(val)); \
i = this->m_data.m_vect.insert(i, boost::move(val)); \
i = this->m_data.m_vect.insert(i, boost::move(val)); \
return i; \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint_equal(const_iterator hint, \
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type \
BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n); \
value_type &val = vval; \
insert_commit_data data; \
priv_insert_equal_prepare(hint, val, data); \
return priv_insert_commit(data, boost::move(val)); \
return priv_insert_commit(data, boost::move(val)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator erase(const_iterator position)
{ return this->m_data.m_vect.erase(position); }
@@ -571,8 +557,6 @@ class flat_tree
// insert val before pos
// else
// insert val before upper_bound(val)
// else if pos+1 == end || val <= *(pos+1)
// insert val after pos
// else
// insert val before lower_bound(val)
const value_compare &value_comp = this->m_data;
@@ -586,10 +570,6 @@ class flat_tree
this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
}
}
//Works, but increases code complexity
//else if (++pos == this->end() || !value_comp(*pos, val)){
// return this->m_data.m_vect.insert(pos, val);
//}
else{
data.position =
this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
@@ -838,7 +818,7 @@ swap(flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
flat_tree<Key,Value,KeyOfValue,Compare,A>& y)
{ x.swap(y); }
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
/*
@@ -846,7 +826,7 @@ swap(flat_tree<Key,Value,KeyOfValue,Compare,A>& x,
//!specialization for optimizations
template <class K, class V, class KOV,
class C, class A>
struct has_trivial_destructor_after_move<boost::container::containers_detail::flat_tree<K, V, KOV, C, A> >
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<K, V, KOV, C, A> >
{
static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
};
@@ -855,4 +835,4 @@ struct has_trivial_destructor_after_move<boost::container::containers_detail::fl
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINERS_FLAT_TREE_HPP
#endif // BOOST_CONTAINER_FLAT_TREE_HPP

View File

@@ -0,0 +1,88 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2011.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
/////////////////////////////////////////////////////////////////////////////
// This code was modified from the code posted by Alexandre Courpron in his
// article "Interface Detection" in The Code Project:
// http://www.codeproject.com/KB/architecture/Detector.aspx
///////////////////////////////////////////////////////////////////////////////
// Copyright 2007 Alexandre Courpron
//
// Permission to use, copy, modify, redistribute and sell this software,
// provided that this copyright notice appears on all copies of the software.
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
#define BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
#include <boost/container/detail/config_begin.hpp>
namespace boost {
namespace container {
namespace function_detector {
typedef char NotFoundType;
struct StaticFunctionType { NotFoundType x [2]; };
struct NonStaticFunctionType { NotFoundType x [3]; };
enum
{ NotFound = 0,
StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ),
NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
};
} //namespace boost {
} //namespace container {
} //namespace function_detector {
#define BOOST_CONTAINER_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
namespace boost { \
namespace container { \
namespace function_detector { \
template < class T, \
class NonStaticType, \
class NonStaticConstType, \
class StaticType > \
class DetectMember_##InstantiationKey_##Identifier { \
template < NonStaticType > \
struct TestNonStaticNonConst ; \
\
template < NonStaticConstType > \
struct TestNonStaticConst ; \
\
template < StaticType > \
struct TestStatic ; \
\
template <class U > \
static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
\
template <class U > \
static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
\
template <class U> \
static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
\
template <class U> \
static NotFoundType Test( ... ); \
public : \
static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
};\
}}} //namespace boost::container::function_detector {
#define BOOST_CONTAINER_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
::boost::container::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
ReturnType (Class::*)Params,\
ReturnType (Class::*)Params const,\
ReturnType (*)Params \
>::check
#include <boost/container/detail/config_end.hpp>
#endif //@ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP

View File

@@ -11,8 +11,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -21,8 +21,9 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
#include <boost/container/detail/stored_ref.hpp>
#else
@@ -368,7 +369,7 @@ class repeat_iterator
{ return m_num - other.m_num; }
};
template <class T, class E, class Difference /*= std::ptrdiff_t*/>
template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
class emplace_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
@@ -377,7 +378,7 @@ class emplace_iterator
public:
typedef Difference difference_type;
explicit emplace_iterator(E&e)
explicit emplace_iterator(EmplaceFunctor&e)
: m_num(1), m_pe(&e){}
emplace_iterator()
@@ -453,12 +454,13 @@ class emplace_iterator
const T* operator->() const
{ return &(dereference()); }
void construct_in_place(T* ptr)
{ (*m_pe)(ptr); }
template<class A>
void construct_in_place(A &a, T* ptr)
{ (*m_pe)(a, ptr); }
private:
difference_type m_num;
E * m_pe;
EmplaceFunctor * m_pe;
void increment()
{ --m_num; }
@@ -485,54 +487,54 @@ class emplace_iterator
{ return difference_type(m_num - other.m_num); }
};
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template<class T, class ...Args>
template<class ...Args>
struct emplace_functor
{
typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
emplace_functor(Args&&... args)
: args_(args...)
{}
void operator()(T *ptr)
{ emplace_functor::inplace_impl(ptr, index_tuple_t()); }
template<class A, class T>
void operator()(A &a, T *ptr)
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
template<int ...IdxPack>
void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
{ ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); }
template<class A, class T, int ...IdxPack>
void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
{
allocator_traits<A>::construct
(a, ptr, container_detail::stored_ref<Args>::forward
(container_detail::get<IdxPack>(args_))...);
}
containers_detail::tuple<Args&...> args_;
container_detail::tuple<Args&...> args_;
};
#else
template<class T>
struct emplace_functor
{
emplace_functor()
{}
void operator()(T *ptr)
{ new(ptr) T(); }
};
#define BOOST_PP_LOCAL_MACRO(n) \
template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \
BOOST_PP_EXPR_IF(n, template <) \
BOOST_PP_ENUM_PARAMS(n, class P) \
BOOST_PP_EXPR_IF(n, >) \
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
{ \
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
: BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
\
void operator()(T *ptr) \
template<class A, class T> \
void operator()(A &a, T *ptr) \
{ \
new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
allocator_traits<A>::construct \
(a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
} \
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif
@@ -542,5 +544,5 @@ struct emplace_functor
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP

View File

@@ -22,7 +22,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
// Greatest common divisor and least common multiple
@@ -104,7 +104,7 @@ inline std::size_t floor_log2 (std::size_t x)
return log2;
}
} // namespace containers_detail
} // namespace container_detail
} // namespace container
} // namespace boost

View File

@@ -10,8 +10,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -21,7 +21,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template <class T, T val>
struct integral_constant
@@ -34,6 +34,7 @@ template< bool C_ >
struct bool_ : integral_constant<bool, C_>
{
static const bool value = C_;
operator bool() const { return bool_::value; }
};
typedef bool_<true> true_;
@@ -147,9 +148,9 @@ struct ls_zeros<1>
static const std::size_t value = 0;
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
#define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
#include "config_begin.hpp"
#include <boost/container/container_fwd.hpp>
@@ -17,13 +17,13 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/transform_iterator.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/move/move.hpp>
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class VoidPointer>
class basic_multiallocation_chain
@@ -33,8 +33,10 @@ class basic_multiallocation_chain
,bi::link_mode<bi::normal_link>
> node;
typedef typename boost::pointer_to_other<VoidPointer, char>::type char_ptr;
typedef typename std::iterator_traits<char_ptr>::difference_type difference_type;
typedef typename boost::intrusive::pointer_traits
<VoidPointer>::template rebind_pointer<char>::type char_ptr;
typedef typename boost::intrusive::
pointer_traits<char_ptr>::difference_type difference_type;
typedef bi::slist< node
, bi::linear<true>
@@ -44,7 +46,7 @@ class basic_multiallocation_chain
slist_impl_t slist_impl_;
static node & to_node(VoidPointer p)
{ return *static_cast<node*>(static_cast<void*>(containers_detail::get_pointer(p))); }
{ return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
@@ -140,7 +142,7 @@ class basic_multiallocation_chain
template<class T>
struct cast_functor
{
typedef typename containers_detail::add_reference<T>::type result_type;
typedef typename container_detail::add_reference<T>::type result_type;
template<class U>
result_type operator()(U &ptr) const
{ return *static_cast<T*>(static_cast<void*>(&ptr)); }
@@ -154,18 +156,18 @@ class transform_multiallocation_chain
MultiallocationChain holder_;
typedef typename MultiallocationChain::void_pointer void_pointer;
typedef typename boost::pointer_to_other
<void_pointer, T>::type pointer;
typedef typename boost::intrusive::pointer_traits
<void_pointer>::template rebind_pointer<T>::type pointer;
static pointer cast(void_pointer p)
{
return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
return pointer(static_cast<T*>(container_detail::to_raw_pointer(p)));
}
public:
typedef transform_iterator
< typename MultiallocationChain::iterator
, containers_detail::cast_functor <T> > iterator;
, container_detail::cast_functor <T> > iterator;
typedef typename MultiallocationChain::size_type size_type;
transform_multiallocation_chain()
@@ -243,10 +245,10 @@ class transform_multiallocation_chain
}}}
// namespace containers_detail {
// namespace container_detail {
// namespace container {
// namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
#endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -27,10 +27,11 @@
#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/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp>
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -39,19 +40,20 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
template <class Allocator>
template <class A>
struct scoped_deallocator
{
typedef typename Allocator::pointer pointer;
typedef containers_detail::integral_constant<unsigned,
boost::container::containers_detail::
version<Allocator>::value> alloc_version;
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private:
void priv_deallocate(allocator_v1)
@@ -65,9 +67,9 @@ struct scoped_deallocator
public:
pointer m_ptr;
Allocator& m_alloc;
A& m_alloc;
scoped_deallocator(pointer p, Allocator& a)
scoped_deallocator(pointer p, A& a)
: m_ptr(p), m_alloc(a)
{}
@@ -88,7 +90,8 @@ struct scoped_deallocator
template <class A>
class allocator_destroyer_and_chain_builder
{
typedef typename A::value_type value_type;
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
A & a_;
@@ -100,17 +103,17 @@ class allocator_destroyer_and_chain_builder
{}
void operator()(const typename A::pointer &p)
{
value_type *vp = containers_detail::get_pointer(p);
vp->~value_type();
c_.push_front(vp);
{
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
c_.push_front(p);
}
};
template <class A>
class allocator_multialloc_chain_node_deallocator
{
typedef typename A::value_type value_type;
typedef allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename A::multiallocation_chain multiallocation_chain;
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
@@ -132,7 +135,6 @@ class allocator_multialloc_chain_node_deallocator
}
};
template<class ValueCompare, class Node>
struct node_compare
: private ValueCompare
@@ -155,70 +157,90 @@ struct node_compare
{ return ValueCompare::operator()(a.get_data(), b.get_data()); }
};
template<class A, class ICont>
template<class A, class ICont, class Pred = container_detail::nat>
struct node_alloc_holder
{
typedef node_alloc_holder<A, ICont> self_t;
typedef typename A::value_type value_type;
typedef typename ICont::value_type Node;
typedef typename A::template rebind<Node>::other NodeAlloc;
typedef A ValAlloc;
typedef typename NodeAlloc::pointer NodePtr;
typedef containers_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename NodeAlloc::size_type size_type;
typedef typename NodeAlloc::difference_type difference_type;
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
typedef containers_detail::integral_constant<unsigned,
boost::container::containers_detail::
typedef allocator_traits<A> allocator_traits_type;
typedef node_alloc_holder<A, ICont> self_t;
typedef typename allocator_traits_type::value_type value_type;
typedef typename ICont::value_type Node;
typedef typename allocator_traits_type::template
portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef A ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename node_allocator_traits_type::size_type size_type;
typedef typename node_allocator_traits_type::difference_type difference_type;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<NodeAlloc>::value> alloc_version;
typedef typename ICont::iterator icont_iterator;
typedef typename ICont::const_iterator icont_citerator;
typedef allocator_destroyer<NodeAlloc> Destroyer;
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
private:
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
public:
node_alloc_holder(const ValAlloc &a)
//Constructors for sequence containers
node_alloc_holder()
: members_()
{}
explicit node_alloc_holder(const ValAlloc &a)
: members_(a)
{}
node_alloc_holder(const node_alloc_holder &other)
: members_(other.node_alloc())
explicit node_alloc_holder(const node_alloc_holder &x)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
{}
node_alloc_holder(BOOST_RV_REF(node_alloc_holder) other)
: members_(boost::move(other.node_alloc()))
{ this->swap(other); }
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
: members_(boost::move(x.node_alloc()))
{ this->icont().swap(x.icont()); }
node_alloc_holder & operator=(BOOST_COPY_ASSIGN_REF(node_alloc_holder) other)
{ members_.assign(other.node_alloc()); }
node_alloc_holder & operator=(BOOST_RV_REF(node_alloc_holder) other)
{ members_.assign(other.node_alloc()); }
template<class Pred>
node_alloc_holder(const ValAlloc &a, const Pred &c)
: members_(a, typename ICont::value_compare(c))
//Constructors for associative containers
explicit node_alloc_holder(const ValAlloc &a, const Pred &c)
: members_(a, c)
{}
template<class Pred>
node_alloc_holder(BOOST_RV_REF(ValAlloc) a, const Pred &c)
: members_(a, typename ICont::value_compare(c))
explicit node_alloc_holder(const node_alloc_holder &x, const Pred &c)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
{}
template<class Pred>
node_alloc_holder(const node_alloc_holder &other, const Pred &c)
: members_(other.node_alloc(), typename ICont::value_compare(c))
explicit node_alloc_holder(const Pred &c)
: members_(c)
{}
//helpers for move assignments
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const Pred &c)
: members_(boost::move(x.node_alloc()), c)
{ this->icont().swap(x.icont()); }
void copy_assign_alloc(const node_alloc_holder &x)
{
container_detail::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag;
container_detail::assign_alloc( static_cast<NodeAlloc &>(this->members_)
, static_cast<const NodeAlloc &>(x.members_), flag);
}
void move_assign_alloc( node_alloc_holder &x)
{
container_detail::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
container_detail::move_alloc( static_cast<NodeAlloc &>(this->members_)
, static_cast<NodeAlloc &>(x.members_), flag);
}
~node_alloc_holder()
{ this->clear(alloc_version()); }
size_type max_size() const
{ return this->node_alloc().max_size(); }
{ return allocator_traits_type::max_size(this->node_alloc()); }
NodePtr allocate_one()
{ return this->allocate_one(alloc_version()); }
@@ -229,131 +251,100 @@ struct node_alloc_holder
NodePtr allocate_one(allocator_v2)
{ return this->node_alloc().allocate_one(); }
void deallocate_one(NodePtr p)
void deallocate_one(const NodePtr &p)
{ return this->deallocate_one(p, alloc_version()); }
void deallocate_one(NodePtr p, allocator_v1)
void deallocate_one(const NodePtr &p, allocator_v1)
{ this->node_alloc().deallocate(p, 1); }
void deallocate_one(NodePtr p, allocator_v2)
void deallocate_one(const NodePtr &p, allocator_v2)
{ this->node_alloc().deallocate_one(p); }
template<class Convertible1, class Convertible2>
static void construct(const NodePtr &ptr,
/*
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 = containers_detail::get_pointer(ptr);
Node *nodeptr = container_detail::to_raw_pointer(ptr);
//Hook constructor does not throw
new(static_cast<hook_type*>(nodeptr))hook_type();
allocator_traits<A>::construct(a, static_cast<hook_type*>(nodeptr));
//Now construct pair members_holder
value_type *valueptr = &nodeptr->get_data();
new((void*)&valueptr->first) first_type(boost::move(value.first));
allocator_traits<A>::construct(a, &valueptr->first, boost::move(value.first));
BOOST_TRY{
new((void*)&valueptr->second) second_type(boost::move(value.second));
allocator_traits<A>::construct(a, &valueptr->second, boost::move(value.second));
}
BOOST_CATCH(...){
valueptr->first.~first_type();
static_cast<hook_type*>(nodeptr)->~hook_type();
allocator_traits<A>::destroy(a, &valueptr->first);
BOOST_RETHROW
}
BOOST_CATCH_END
}
static void destroy(const NodePtr &ptr)
{ containers_detail::get_pointer(ptr)->~Node(); }
Deallocator create_node_and_deallocator()
{
return Deallocator(this->allocate_one(), this->node_alloc());
*/
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
/*
template<class A, class ...Args>
static void construct(A &a, const NodePtr &ptr, Args &&...args)
{
}
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
template<class ...Args>
static void construct(const NodePtr &ptr, Args &&...args)
{ new((void*)containers_detail::get_pointer(ptr)) Node(boost::forward<Args>(args)...); }
*/
template<class ...Args>
NodePtr create_node(Args &&...args)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p, boost::forward<Args>(args)...);
allocator_traits<NodeAlloc>::construct
(this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward<Args>(args)...);
node_deallocator.release();
return (p);
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
static void construct(const NodePtr &ptr)
{ new((void*)containers_detail::get_pointer(ptr)) Node(); }
NodePtr create_node()
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p);
node_deallocator.release();
return (p);
}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
new((void*)containers_detail::get_pointer(ptr)) \
Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p = this->allocate_one(); \
Deallocator node_deallocator(p, this->node_alloc()); \
self_t::construct(p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
allocator_traits<NodeAlloc>::construct \
(this->node_alloc(), container_detail::to_raw_pointer(p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
node_deallocator.release(); \
return (p); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template<class It>
NodePtr create_node_from_it(It it)
NodePtr create_node_from_it(const It &it)
{
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::container::construct_in_place(containers_detail::get_pointer(p), it);
::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
node_deallocator.release();
return (p);
}
void destroy_node(NodePtr node)
void destroy_node(const NodePtr &nodep)
{
self_t::destroy(node);
this->deallocate_one(node);
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
this->deallocate_one(nodep);
}
void swap(node_alloc_holder &x)
{
NodeAlloc& this_alloc = this->node_alloc();
NodeAlloc& other_alloc = x.node_alloc();
if (this_alloc != other_alloc){
containers_detail::do_swap(this_alloc, other_alloc);
}
this->icont().swap(x.icont());
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
}
template<class FwdIterator, class Inserter>
@@ -369,11 +360,11 @@ struct node_alloc_holder
Node *p = 0;
BOOST_TRY{
for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
p = containers_detail::get_pointer(mem.front());
p = container_detail::to_raw_pointer(mem.front());
mem.pop_front();
//This can throw
constructed = 0;
boost::container::construct_in_place(p, beg);
boost::container::construct_in_place(this->node_alloc(), p, beg);
++constructed;
//This can throw in some containers (predicate might throw)
inserter(*p);
@@ -381,7 +372,7 @@ struct node_alloc_holder
}
BOOST_CATCH(...){
if(constructed){
this->destroy(p);
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(p));
}
this->node_alloc().deallocate_individual(boost::move(mem));
BOOST_RETHROW
@@ -404,10 +395,10 @@ struct node_alloc_holder
this->node_alloc().deallocate_individual(boost::move(chain));
}
icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
{
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
@@ -437,44 +428,38 @@ struct node_alloc_holder
node_alloc_holder &m_holder;
};
struct destroyer
{
destroyer(node_alloc_holder &holder)
: m_holder(holder)
{}
void operator()(NodePtr n) const
{ m_holder.destroy_node(n); }
node_alloc_holder &m_holder;
};
struct members_holder
: public NodeAlloc
{
private:
members_holder(const members_holder&);
members_holder & operator=(const members_holder&);
public:
template<class ConvertibleToAlloc>
members_holder(const ConvertibleToAlloc &c2alloc)
: NodeAlloc(c2alloc)
{}
template<class ConvertibleToAlloc, class Pred>
members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
: NodeAlloc(c2alloc), m_icont(c)
members_holder()
: NodeAlloc(), m_icont()
{}
template<class ConvertibleToAlloc>
void assign (const ConvertibleToAlloc &c2alloc)
{
NodeAlloc::operator=(c2alloc);
}
explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
, m_icont()
{}
template<class ConvertibleToAlloc>
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const Pred &c)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
, m_icont(typename ICont::value_compare(c))
{}
explicit members_holder(const Pred &c)
: NodeAlloc()
, m_icont(typename ICont::value_compare(c))
{}
//The intrusive container
ICont m_icont;
} members_;
};
ICont &non_const_icont() const
{ return const_cast<ICont&>(this->members_.m_icont); }
@@ -490,12 +475,14 @@ struct node_alloc_holder
const NodeAlloc &node_alloc() const
{ return static_cast<const NodeAlloc &>(this->members_); }
members_holder members_;
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
#endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_

View File

@@ -19,7 +19,7 @@
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/container/detail/type_traits.hpp>
@@ -32,7 +32,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class SegmentManagerBase>
class private_node_pool_impl
@@ -82,7 +82,7 @@ class private_node_pool_impl
//!Returns the segment manager. Never throws
segment_manager_base_type* get_segment_manager_base()const
{ return containers_detail::get_pointer(mp_segment_mngr_base); }
{ return container_detail::to_raw_pointer(mp_segment_mngr_base); }
void *allocate_node()
{ return priv_alloc_node(); }
@@ -346,8 +346,8 @@ class private_node_pool_impl
}
private:
typedef typename boost::pointer_to_other
<void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
typedef typename boost::intrusive::pointer_traits
<void_pointer>::template rebind_pointer<segment_manager_base_type>::type segment_mngr_base_ptr_t;
const size_type m_nodes_per_block;
const size_type m_real_node_size;
@@ -358,7 +358,7 @@ class private_node_pool_impl
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {

View File

@@ -10,8 +10,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
#define BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -28,13 +28,13 @@
#include <boost/move/move.hpp>
#include <boost/type_traits/is_class.hpp>
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template <class T1, class T2>
struct pair;
@@ -143,13 +143,13 @@ struct pair
/*
//Variadic versions
template<class U>
pair(BOOST_CONTAINERS_PARAM(U, u), typename containers_detail::disable_if
< containers_detail::is_pair< typename containers_detail::remove_ref_const<U>::type >, pair_nat>::type* = 0)
pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if
< container_detail::is_pair< typename container_detail::remove_ref_const<U>::type >, pair_nat>::type* = 0)
: first(::boost::forward<U>(u))
, second()
{}
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template<class U, class V, class ...Args>
pair(U &&u, V &&v)
@@ -161,13 +161,13 @@ struct pair
#define BOOST_PP_LOCAL_MACRO(n) \
template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
pair(BOOST_CONTAINERS_PARAM(U, u) \
,BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
pair(BOOST_CONTAINER_PP_PARAM(U, u) \
,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: first(::boost::forward<U>(u)) \
, second(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
, second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif
*/
@@ -280,7 +280,7 @@ inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
swap(x.second, y.second);
}
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
@@ -291,7 +291,7 @@ template<class T>
struct is_enum;
template<class T, class U>
struct is_enum< ::boost::container::containers_detail::pair<T, U> >
struct is_enum< ::boost::container::container_detail::pair<T, U> >
{
static const bool value = false;
};
@@ -299,14 +299,14 @@ struct is_enum< ::boost::container::containers_detail::pair<T, U> >
//This specialization is needed to avoid instantiation of pair in
//is_class, and allow recursive maps.
template <class T1, class T2>
struct is_class< ::boost::container::containers_detail::pair<T1, T2> >
struct is_class< ::boost::container::container_detail::pair<T1, T2> >
: public ::boost::true_type
{};
#ifdef BOOST_NO_RVALUE_REFERENCES
template<class T1, class T2>
struct has_move_emulation_enabled< ::boost::container::containers_detail::pair<T1, T2> >
struct has_move_emulation_enabled< ::boost::container::container_detail::pair<T1, T2> >
: ::boost::true_type
{};
@@ -317,4 +317,4 @@ struct has_move_emulation_enabled< ::boost::container::containers_detail::pair<T
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_PAIR_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP

View File

@@ -21,7 +21,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class VoidPointer>
struct node_slist
@@ -43,7 +43,7 @@ struct is_stateless_segment_manager
static const bool value = false;
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {

View File

@@ -8,32 +8,43 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
#define BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#ifndef BOOST_NO_RVALUE_REFERENCES
#include <boost/container/detail/stored_ref.hpp>
#endif
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
#include <boost/container/detail/workaround.hpp>
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#error "This file is not needed when perfect forwarding is available"
#endif
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//#error "This file is not needed when perfect forwarding is available"
#endif //BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/punctuation/paren_if.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#define BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS 10
#define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
//Note:
//We define template parameters as const references to
@@ -42,100 +53,126 @@
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind rvalues with non-const references, we have to be ugly
#ifndef BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
#define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
//!
#else
#define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
#define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
//!
#endif
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
#ifndef BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINERS_PARAM(U, u) \
#define BOOST_CONTAINER_PP_PARAM(U, u) \
U && u \
//!
#else
#define BOOST_CONTAINERS_PARAM(U, u) \
#define BOOST_CONTAINER_PP_PARAM(U, u) \
const U & u \
//!
#endif
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
//!
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
//!
#else
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
//!
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
//!
#endif
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
#else
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
//!
#endif
#else //BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINERS_AUX_PARAM_INC(z, n, data) \
BOOST_PP_CAT(++m_p, n) \
//!
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
//!
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
#ifndef BOOST_NO_RVALUE_REFERENCES
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
#else
#else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
//!
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
//!
#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#else //BOOST_NO_RVALUE_REFERENCES
#else
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
#endif
#define BOOST_CONTAINERS_PP_PARAM_FORWARD(z, n, data) \
boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
::boost::container::containers_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
//!
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
::boost::container::container_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(this->m_p, n) ) \
//!
#else
#else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
//!
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
//!
#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINERS_PP_MEMBER_IT_FORWARD(z, n, data) \
BOOST_PP_CAT(*m_p, n) \
#define BOOST_CONTAINER_PP_PARAM_INC(z, n, data) \
BOOST_PP_CAT(++this->m_p, n) \
//!
#define BOOST_CONTAINER_PP_IDENTITY(z, n, data) data
#define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
//!
#define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
//!
#define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
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 \
//!
#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
static BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n); \
//!
#define BOOST_CONTAINER_PP_PARAM_PASS(z, n, data) \
BOOST_PP_CAT(p, n) \
//!
#define BOOST_CONTAINER_PP_FWD_TYPE(z, n, data) \
typename ::boost::move_detail::forward_type< BOOST_PP_CAT(P, n) >::type \
//!
#include <boost/container/detail/config_end.hpp>
#else
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#error "This file is not needed when perfect forwarding is available"
#endif
#endif //#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
//#else
//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//#error "This file is not needed when perfect forwarding is available"
//#endif //BOOST_CONTAINER_PERFECT_FORWARDING
#endif //#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
#define BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
#ifndef BOOST_CONTAINER_DETAIL_STORED_REF_HPP
#define BOOST_CONTAINER_DETAIL_STORED_REF_HPP
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
@@ -18,7 +18,7 @@
namespace boost{
namespace container{
namespace containers_detail{
namespace container_detail{
template<class T>
struct stored_ref
@@ -79,7 +79,7 @@ struct stored_ref<T&>
{ return t; }
};
} //namespace containers_detail{
} //namespace container_detail{
} //namespace container{
} //namespace boost{
@@ -89,4 +89,4 @@ struct stored_ref<T&>
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
#endif //BOOST_CONTAINER_DETAIL_STORED_REF_HPP

View File

@@ -11,8 +11,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
#define BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -59,7 +59,7 @@ class transform_iterator
: public UnaryFunction
, public std::iterator
< typename Iterator::iterator_category
, typename containers_detail::remove_reference<typename UnaryFunction::result_type>::type
, typename container_detail::remove_reference<typename UnaryFunction::result_type>::type
, typename Iterator::difference_type
, operator_arrow_proxy<typename UnaryFunction::result_type>
, typename UnaryFunction::result_type>
@@ -173,4 +173,4 @@ make_transform_iterator(Iterator it, UnaryFunc fun)
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP

View File

@@ -8,15 +8,15 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_TREE_HPP
#define BOOST_CONTAINERS_TREE_HPP
#ifndef BOOST_CONTAINER_TREE_HPP
#define BOOST_CONTAINER_TREE_HPP
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/move/move.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/intrusive/rbtree.hpp>
@@ -27,7 +27,8 @@
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#include <boost/container/allocator/allocator_traits.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -37,7 +38,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class Key, class Value, class KeyCompare, class KeyOfValue>
struct value_compare_impl
@@ -82,10 +83,10 @@ struct value_compare_impl
template<class VoidPointer>
struct rbtree_hook
{
typedef typename containers_detail::bi::make_set_base_hook
< containers_detail::bi::void_pointer<VoidPointer>
, containers_detail::bi::link_mode<containers_detail::bi::normal_link>
, containers_detail::bi::optimize_size<true>
typedef typename container_detail::bi::make_set_base_hook
< container_detail::bi::void_pointer<VoidPointer>
, container_detail::bi::link_mode<container_detail::bi::normal_link>
, container_detail::bi::optimize_size<true>
>::type type;
};
@@ -105,6 +106,10 @@ template <class T, class VoidPointer>
struct rbtree_node
: public rbtree_hook<VoidPointer>::type
{
private:
BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
public:
typedef typename rbtree_hook<VoidPointer>::type hook_type;
typedef T value_type;
@@ -112,8 +117,6 @@ struct rbtree_node
typedef rbtree_node<T, VoidPointer> node_type;
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
rbtree_node()
: m_data()
{}
@@ -122,30 +125,35 @@ struct rbtree_node
: m_data(other.m_data)
{}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
{} \
rbtree_node(BOOST_RV_REF(rbtree_node) other)
: m_data(boost::move(other.m_data))
{}
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
{} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
rbtree_node()
: m_data()
{}
#else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
template<class ...Args>
rbtree_node(Args &&...args)
: m_data(boost::forward<Args>(args)...)
{}
#endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
rbtree_node &operator=(const rbtree_node &other)
{ do_assign(other.m_data); return *this; }
rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
{ do_move(other.m_data); return *this; }
T &get_data()
{
T* ptr = reinterpret_cast<T*>(&this->m_data);
@@ -179,76 +187,88 @@ struct rbtree_node
void do_assign(const V &v)
{ m_data = v; }
public:
template<class Convertible>
static void construct(node_type *ptr, BOOST_FWD_REF(Convertible) convertible)
{ new(ptr) node_type(boost::forward<Convertible>(convertible)); }
template<class A, class B>
void do_move(std::pair<const A, B> &p)
{
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)
{
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); }
};
}//namespace containers_detail {
#if defined(BOOST_NO_RVALUE_REFERENCES)
template<class T, class VoidPointer>
struct has_own_construct_from_it
< boost::container::containers_detail::rbtree_node<T, VoidPointer> >
{
static const bool value = true;
};
#endif
namespace containers_detail {
}//namespace container_detail {
namespace container_detail {
template<class A, class ValueCompare>
struct intrusive_rbtree_type
{
typedef typename A::value_type value_type;
typedef typename boost::pointer_to_other
<typename A::pointer, void>::type void_pointer;
typedef typename containers_detail::rbtree_node
typedef typename boost::container::
allocator_traits<A>::value_type value_type;
typedef typename boost::container::
allocator_traits<A>::void_pointer void_pointer;
typedef typename boost::container::
allocator_traits<A>::size_type size_type;
typedef typename container_detail::rbtree_node
<value_type, void_pointer> node_type;
typedef node_compare<ValueCompare, node_type> node_compare_type;
typedef typename containers_detail::bi::make_rbtree
typedef typename container_detail::bi::make_rbtree
<node_type
,containers_detail::bi::compare<node_compare_type>
,containers_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
,containers_detail::bi::constant_time_size<true>
,containers_detail::bi::size_type<typename A::size_type>
,container_detail::bi::compare<node_compare_type>
,container_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
,container_detail::bi::constant_time_size<true>
,container_detail::bi::size_type<size_type>
>::type container_type;
typedef container_type type ;
};
} //namespace containers_detail {
} //namespace container_detail {
namespace containers_detail {
namespace container_detail {
template <class Key, class Value, class KeyOfValue,
class KeyCompare, class A>
class rbtree
: protected containers_detail::node_alloc_holder
<A, typename containers_detail::intrusive_rbtree_type
: protected container_detail::node_alloc_holder
< A
, typename container_detail::intrusive_rbtree_type
<A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue>
>::type
, KeyCompare
>
{
typedef typename containers_detail::intrusive_rbtree_type
<A, value_compare_impl
typedef typename container_detail::intrusive_rbtree_type
< A, value_compare_impl
<Key, Value, KeyCompare, KeyOfValue>
>::type Icont;
typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
>::type Icont;
typedef container_detail::node_alloc_holder
<A, Icont, KeyCompare> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef rbtree < Key, Value, KeyOfValue
, KeyCompare, A> ThisType;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef typename Icont::iterator iiterator;
typedef typename Icont::const_iterator iconst_iterator;
typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
, KeyCompare, A> ThisType;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef typename Icont::iterator iiterator;
typedef typename Icont::const_iterator iconst_iterator;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
class RecyclingCloner;
friend class RecyclingCloner;
class RecyclingCloner
{
public:
@@ -258,10 +278,8 @@ class rbtree
NodePtr operator()(const Node &other) const
{
// if(!m_icont.empty()){
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
//First recycle a node (this can't throw)
//NodePtr p = m_icont.unlink_leftmost_without_rebalance();
try{
//This can throw
*p = other;
@@ -284,6 +302,44 @@ class rbtree
AllocHolder &m_holder;
Icont &m_icont;
};
class RecyclingMoveCloner;
friend class RecyclingMoveCloner;
class RecyclingMoveCloner
{
public:
RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree)
: m_holder(holder), m_icont(irbtree)
{}
NodePtr operator()(const Node &other) const
{
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
//First recycle a node (this can't throw)
try{
//This can throw
*p = boost::move(other);
return p;
}
catch(...){
//If there is an exception destroy the whole source
m_holder.destroy_node(p);
while((p = m_icont.unlink_leftmost_without_rebalance())){
m_holder.destroy_node(p);
}
throw;
}
}
else{
return m_holder.create_node(other);
}
}
AllocHolder &m_holder;
Icont &m_icont;
};
BOOST_COPYABLE_AND_MOVABLE(rbtree)
public:
@@ -294,12 +350,18 @@ class rbtree
typedef KeyCompare key_compare;
typedef value_compare_impl< Key, Value
, KeyCompare, KeyOfValue> value_compare;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef typename A::size_type size_type;
typedef typename A::difference_type difference_type;
typedef typename boost::container::
allocator_traits<A>::pointer pointer;
typedef typename boost::container::
allocator_traits<A>::const_pointer const_pointer;
typedef typename boost::container::
allocator_traits<A>::reference reference;
typedef typename boost::container::
allocator_traits<A>::const_reference const_reference;
typedef typename boost::container::
allocator_traits<A>::size_type size_type;
typedef typename boost::container::
allocator_traits<A>::difference_type difference_type;
typedef difference_type rbtree_difference_type;
typedef pointer rbtree_pointer;
typedef const_pointer rbtree_const_pointer;
@@ -436,8 +498,11 @@ class rbtree
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
rbtree(const key_compare& comp = key_compare(),
const allocator_type& a = allocator_type())
rbtree()
: AllocHolder(key_compare())
{}
rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
: AllocHolder(a, comp)
{}
@@ -467,26 +532,32 @@ class rbtree
}
rbtree(BOOST_RV_REF(rbtree) x)
: AllocHolder(x, x.key_comp())
{ this->swap(x); }
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
{}
~rbtree()
{} //AllocHolder clears the tree
rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
{
if (this != &x) {
if (&x != this){
NodeAlloc &this_alloc = this->get_stored_allocator();
const NodeAlloc &x_alloc = x.get_stored_allocator();
container_detail::bool_<allocator_traits<NodeAlloc>::
propagate_on_container_copy_assignment::value> flag;
if(flag && this_alloc != x_alloc){
this->clear();
}
this->AllocHolder::copy_assign_alloc(x);
//Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed
//automatically
Icont other_tree(this->icont().value_comp());
other_tree.swap(this->icont());
Icont other_tree(boost::move(this->icont()));
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
(x.icont()
, RecyclingCloner(*this, other_tree)
//, AllocHolder::cloner(*this)
, Destroyer(this->node_alloc()));
//If there are remaining nodes, destroy them
@@ -498,8 +569,41 @@ class rbtree
return *this;
}
rbtree& operator=(BOOST_RV_REF(rbtree) mx)
{ this->clear(); this->swap(mx); return *this; }
rbtree& operator=(BOOST_RV_REF(rbtree) x)
{
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
NodeAlloc &x_alloc = x.node_alloc();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy and swap pointers
this->clear();
this->icont() = boost::move(x.icont());
//Move allocator if needed
this->AllocHolder::move_assign_alloc(x);
}
//If unequal allocators, then do a one by one move
else{
//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()));
//Now recreate the source tree reusing nodes stored by other_tree
this->icont().clone_from
(x.icont()
, RecyclingMoveCloner(*this, other_tree)
, Destroyer(this->node_alloc()));
//If there are remaining nodes, destroy them
NodePtr p;
while((p = other_tree.unlink_leftmost_without_rebalance())){
AllocHolder::destroy_node(p);
}
}
}
return *this;
}
public:
// accessors:
@@ -677,7 +781,7 @@ class rbtree
public:
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
template <class... Args>
iterator emplace_unique(Args&&... args)
@@ -701,59 +805,43 @@ class rbtree
return iterator(this->icont().insert_equal(hint.get(), *p));
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
iterator emplace_unique()
{ return this->emplace_unique_impl(AllocHolder::create_node()); }
iterator emplace_hint_unique(const_iterator hint)
{ return this->emplace_unique_hint_impl(hint, AllocHolder::create_node()); }
iterator emplace_equal()
{
NodePtr p(AllocHolder::create_node());
return iterator(this->icont().insert_equal(this->icont().end(), *p));
}
iterator emplace_hint_equal(const_iterator hint)
{
NodePtr p(AllocHolder::create_node());
return iterator(this->icont().insert_equal(hint.get(), *p));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
return this->emplace_unique_impl \
(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint_unique(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_unique(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
return this->emplace_unique_hint_impl \
(hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
(hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint_equal(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(hint.get(), *p)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator insert_unique(const_iterator hint, const value_type& v)
{
@@ -1044,7 +1132,7 @@ swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
x.swap(y);
}
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
/*
//!has_trivial_destructor_after_move<> == true_type
@@ -1052,7 +1140,7 @@ swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
template <class K, class V, class KOV,
class C, class A>
struct has_trivial_destructor_after_move
<boost::container::containers_detail::rbtree<K, V, KOV, C, A> >
<boost::container::container_detail::rbtree<K, V, KOV, C, A> >
{
static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
};
@@ -1061,4 +1149,4 @@ struct has_trivial_destructor_after_move
#include <boost/container/detail/config_end.hpp>
#endif //BOOST_CONTAINERS_TREE_HPP
#endif //BOOST_CONTAINER_TREE_HPP

View File

@@ -12,8 +12,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -25,7 +25,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
struct nat{};
@@ -194,10 +194,10 @@ struct remove_ref_const
typedef typename remove_const< typename remove_reference<T>::type >::type type;
};
} // namespace containers_detail
} // namespace container_detail
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#include "config_begin.hpp"
#include <cstdio>
@@ -21,11 +21,12 @@
#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 <algorithm>
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class T>
const T &max_value(const T &a, const T &b)
@@ -55,29 +56,14 @@ SizeType
return max_size;
}
template<class SmartPtr>
struct smart_ptr_type
{
typedef typename SmartPtr::value_type value_type;
typedef value_type *pointer;
static pointer get (const SmartPtr &smartptr)
{ return smartptr.get();}
};
template <class T>
inline T* to_raw_pointer(T* p)
{ return p; }
template<class T>
struct smart_ptr_type<T*>
{
typedef T value_type;
typedef value_type *pointer;
static pointer get (pointer ptr)
{ return ptr;}
};
//!Overload for smart pointers to avoid ADL problems with get_pointer
template<class Ptr>
inline typename smart_ptr_type<Ptr>::pointer
get_pointer(const Ptr &ptr)
{ return smart_ptr_type<Ptr>::get(ptr); }
template <class Pointer>
inline typename Pointer::element_type*
to_raw_pointer(const Pointer &p)
{ return boost::container::container_detail::to_raw_pointer(p.operator->()); }
//!To avoid ADL problems with swap
template <class T>
@@ -87,6 +73,33 @@ inline void do_swap(T& x, T& y)
swap(x, y);
}
template<class AllocatorType>
inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
{ container_detail::do_swap(l, r); }
template<class AllocatorType>
inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type)
{ l = r; }
template<class AllocatorType>
inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
BOOST_CONTAINER_NOEXCEPT
{}
template<class AllocatorType>
inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
{ l = ::boost::move(r); }
//Rounds "orig_size" by excess to round_to bytes
template<class SizeType>
inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
@@ -99,36 +112,36 @@ struct ct_rounded_size
{
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
};
/*
template <class _TypeT>
struct __rw_is_enum
{
struct _C_no { };
struct _C_yes { int _C_dummy [2]; };
struct _C_no { };
struct _C_yes { int _C_dummy [2]; };
struct _C_indirect {
// prevent classes with user-defined conversions from matching
struct _C_indirect {
// prevent classes with user-defined conversions from matching
// use double to prevent float->int gcc conversion warnings
_C_indirect (double);
// use double to prevent float->int gcc conversion warnings
_C_indirect (double);
};
// nested struct gets rid of bogus gcc errors
struct _C_nest {
// supply first argument to prevent HP aCC warnings
static _C_no _C_is (int, ...);
static _C_yes _C_is (int, _C_indirect);
// supply first argument to prevent HP aCC warnings
static _C_no _C_is (int, ...);
static _C_yes _C_is (int, _C_indirect);
static _TypeT _C_make_T ();
static _TypeT _C_make_T ();
};
enum {
_C_val = sizeof (_C_yes)
== sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ()))
&& !::boost::is_fundamental<_TypeT>::value
_C_val = sizeof (_C_yes) == sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ()))
&& !::boost::is_fundamental<_TypeT>::value
};
};
*/
template<class T>
struct move_const_ref_type
@@ -140,11 +153,119 @@ struct move_const_ref_type
>
{};
} //namespace containers_detail {
} //namespace container_detail {
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_move_alloc
//
//////////////////////////////////////////////////////////////////////////////
//! <b>Effects</b>:
//! \code
//! for (; first != last; ++result, ++first)
//! allocator_traits::construct(a, &*result, boost::move(*first));
//! \endcode
//!
//! <b>Returns</b>: result
template
<typename A,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
F uninitialized_move_alloc(A &a, I f, I l, F r)
{
while (f != l) {
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
++f; ++r;
}
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_copy_alloc
//
//////////////////////////////////////////////////////////////////////////////
//! <b>Effects</b>:
//! \code
//! for (; first != last; ++result, ++first)
//! allocator_traits::construct(a, &*result, *first);
//! \endcode
//!
//! <b>Returns</b>: result
template
<typename A,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
F uninitialized_copy_alloc(A &a, I f, I l, F r)
{
while (f != l) {
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
++f; ++r;
}
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_copy_alloc
//
//////////////////////////////////////////////////////////////////////////////
//! <b>Effects</b>:
//! \code
//! for (; first != last; ++result, ++first)
//! allocator_traits::construct(a, &*result, *first);
//! \endcode
//!
//! <b>Returns</b>: result
template
<typename A,
typename F, // F models ForwardIterator
typename T>
void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
{
while (f != l) {
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
++f;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_copy_or_move_alloc
//
//////////////////////////////////////////////////////////////////////////////
template
<typename A
,typename I // I models InputIterator
,typename F> // F models ForwardIterator
F uninitialized_copy_or_move_alloc
(A &a, I f, I l, F r
,typename boost::container::container_detail::enable_if
< boost::move_detail::is_move_iterator<I> >::type* = 0)
{
return ::boost::container::uninitialized_move_alloc(a, f, l, r);
}
template
<typename A
,typename I // I models InputIterator
,typename F> // F models ForwardIterator
F uninitialized_copy_or_move_alloc
(A &a, I f, I l, F r
,typename boost::container::container_detail::disable_if
< boost::move_detail::is_move_iterator<I> >::type* = 0)
{
return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
}
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP

View File

@@ -10,8 +10,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
#define BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -22,7 +22,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<class T>
struct value_init
@@ -31,13 +31,15 @@ struct value_init
: m_t()
{}
operator T &() { return m_t; }
T m_t;
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#define BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -22,7 +22,7 @@
namespace boost {
namespace container {
namespace containers_detail {
namespace container_detail {
template<typename... Values>
class tuple;
@@ -146,8 +146,8 @@ struct build_number_seq<0, index_tuple<Indexes...> >
{ typedef index_tuple<Indexes...> type; };
}}} //namespace boost { namespace container { namespace containers_detail {
}}} //namespace boost { namespace container { namespace container_detail {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP

View File

@@ -13,8 +13,8 @@
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
#include "config_begin.hpp"
@@ -23,13 +23,13 @@
namespace boost{
namespace container {
namespace containers_detail {
namespace container_detail {
//using namespace boost;
template <class T, unsigned V>
struct version_type
: public containers_detail::integral_constant<unsigned, V>
: public container_detail::integral_constant<unsigned, V>
{
typedef T type;
@@ -39,7 +39,7 @@ struct version_type
namespace impl{
template <class T,
bool = containers_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
bool = container_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
struct extract_version
{
static const unsigned value = 1;
@@ -79,14 +79,14 @@ struct version<T, true>
template <class T>
struct version
: public containers_detail::integral_constant<unsigned, impl::version<T>::value>
: public container_detail::integral_constant<unsigned, impl::version<T>::value>
{
};
} //namespace containers_detail {
} //namespace container_detail {
} //namespace container {
} //namespace boost{
#include "config_end.hpp"
#endif //#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP

View File

@@ -8,17 +8,24 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
#define BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
#define BOOST_CONTAINERS_PERFECT_FORWARDING
#define BOOST_CONTAINER_PERFECT_FORWARDING
#endif
#if defined(BOOST_NO_NOEXCEPT)
#define BOOST_CONTAINER_NOEXCEPT
#define BOOST_CONTAINER_NOEXCEPT_IF(x)
#else
#define BOOST_CONTAINER_NOEXCEPT noexcept
#define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
#endif
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_FLAT_MAP_HPP
#define BOOST_CONTAINERS_FLAT_MAP_HPP
#ifndef BOOST_CONTAINER_FLAT_MAP_HPP
#define BOOST_CONTAINER_FLAT_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -26,6 +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/move/move.hpp>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -52,6 +53,23 @@ inline bool operator==(const flat_map<Key,T,Pred,A>& x,
template <class Key, class T, class Pred, class A>
inline bool operator<(const flat_map<Key,T,Pred,A>& x,
const flat_map<Key,T,Pred,A>& y);
namespace container_detail{
template<class D, class S>
static D &force(const S &s)
{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
template<class D, class S>
static D force_copy(S s)
{
D *vp = reinterpret_cast<D *>(&s);
return D(*vp);
}
} //namespace container_detail{
/// @endcond
//! A flat_map is a kind of associative container that supports unique keys (contains at
@@ -86,19 +104,19 @@ class flat_map
private:
BOOST_COPYABLE_AND_MOVABLE(flat_map)
//This is the tree that we should store if pair was movable
typedef containers_detail::flat_tree<Key,
typedef container_detail::flat_tree<Key,
std::pair<Key, T>,
containers_detail::select1st< std::pair<Key, T> >,
container_detail::select1st< std::pair<Key, T> >,
Pred,
A> tree_t;
//This is the real tree stored here. It's based on a movable pair
typedef containers_detail::flat_tree<Key,
containers_detail::pair<Key, T>,
containers_detail::select1st<containers_detail::pair<Key, T> >,
typedef container_detail::flat_tree<Key,
container_detail::pair<Key, T>,
container_detail::select1st<container_detail::pair<Key, T> >,
Pred,
typename A::template
rebind<containers_detail::pair<Key, T> >::other> impl_tree_t;
typename allocator_traits<A>::template portable_rebind_alloc
<container_detail::pair<Key, T> >::type> impl_tree_t;
impl_tree_t m_flat_tree; // flat tree representing flat_map
typedef typename impl_tree_t::value_type impl_value_type;
@@ -112,56 +130,56 @@ class flat_map
typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
typedef typename impl_tree_t::allocator_type impl_allocator_type;
typedef allocator_traits<A> allocator_traits_type;
template<class D, class S>
static D &force(const S &s)
{ return *const_cast<D*>(reinterpret_cast<const D*>(&s)); }
template<class D, class S>
static D force_copy(S s)
{
value_type *vp = reinterpret_cast<value_type *>(&*s);
return D(vp);
}
/// @endcond
public:
// typedefs:
typedef typename impl_tree_t::key_type key_type;
typedef T mapped_type;
typedef typename std::pair<key_type, mapped_type> value_type;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef containers_detail::flat_tree_value_compare
typedef Key key_type;
typedef T mapped_type;
typedef typename std::pair<key_type, mapped_type> value_type;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::const_pointer const_pointer;
typedef typename allocator_traits_type::reference reference;
typedef typename allocator_traits_type::const_reference const_reference;
typedef typename impl_tree_t::size_type size_type;
typedef typename impl_tree_t::difference_type difference_type;
typedef container_detail::flat_tree_value_compare
< Pred
, containers_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare;
typedef Pred key_compare;
typedef typename containers_detail::
get_flat_tree_iterators<pointer>::iterator iterator;
typedef typename containers_detail::
get_flat_tree_iterators<pointer>::const_iterator const_iterator;
typedef typename containers_detail::
, container_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare;
typedef Pred key_compare;
typedef typename container_detail::
get_flat_tree_iterators<pointer>::iterator iterator;
typedef typename container_detail::
get_flat_tree_iterators<pointer>::const_iterator const_iterator;
typedef typename container_detail::
get_flat_tree_iterators
<pointer>::reverse_iterator reverse_iterator;
typedef typename containers_detail::
<pointer>::reverse_iterator reverse_iterator;
typedef typename container_detail::
get_flat_tree_iterators
<pointer>::const_reverse_iterator const_reverse_iterator;
typedef typename impl_tree_t::size_type size_type;
typedef typename impl_tree_t::difference_type difference_type;
typedef A allocator_type;
typedef A stored_allocator_type;
<pointer>::const_reverse_iterator const_reverse_iterator;
typedef A allocator_type;
typedef A stored_allocator_type;
public:
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
//! <b>Complexity</b>: Constant.
flat_map()
: m_flat_tree() {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
//! comparison object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit flat_map(const Pred& comp = Pred(), const allocator_type& a = allocator_type())
: m_flat_tree(comp, force<impl_allocator_type>(a)) {}
explicit flat_map(const Pred& comp, const allocator_type& a = allocator_type())
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a)) {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
//! allocator, and inserts elements from the range [first ,last ).
@@ -171,7 +189,7 @@ class flat_map
template <class InputIterator>
flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
: m_flat_tree(comp, force<impl_allocator_type>(a))
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{ m_flat_tree.insert_unique(first, last); }
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
@@ -224,27 +242,27 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
key_compare key_comp() const
{ return force<key_compare>(m_flat_tree.key_comp()); }
{ return container_detail::force<key_compare>(m_flat_tree.key_comp()); }
//! <b>Effects</b>: Returns an object of value_compare constructed out
//! of the comparison object.
//!
//! <b>Complexity</b>: Constant.
value_compare value_comp() const
{ return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
{ return value_compare(container_detail::force<key_compare>(m_flat_tree.key_comp())); }
//! <b>Effects</b>: Returns a copy of the Allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const
{ return force<allocator_type>(m_flat_tree.get_allocator()); }
{ return container_detail::force<allocator_type>(m_flat_tree.get_allocator()); }
const stored_allocator_type &get_stored_allocator() const
{ return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
stored_allocator_type &get_stored_allocator()
{ return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the container.
//!
@@ -252,7 +270,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
iterator begin()
{ return force_copy<iterator>(m_flat_tree.begin()); }
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
@@ -260,7 +278,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_iterator begin() const
{ return force<const_iterator>(m_flat_tree.begin()); }
{ return container_detail::force<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
@@ -268,7 +286,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_iterator cbegin() const
{ return force<const_iterator>(m_flat_tree.cbegin()); }
{ return container_detail::force<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
//!
@@ -276,7 +294,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
iterator end()
{ return force_copy<iterator>(m_flat_tree.end()); }
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
@@ -284,7 +302,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_iterator end() const
{ return force<const_iterator>(m_flat_tree.end()); }
{ return container_detail::force<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
@@ -292,7 +310,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_iterator cend() const
{ return force<const_iterator>(m_flat_tree.cend()); }
{ return container_detail::force<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -301,7 +319,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
reverse_iterator rbegin()
{ return force<reverse_iterator>(m_flat_tree.rbegin()); }
{ return container_detail::force<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -310,7 +328,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator rbegin() const
{ return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -319,7 +337,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator crbegin() const
{ return force<const_reverse_iterator>(m_flat_tree.crbegin()); }
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
//! of the reversed container.
@@ -328,7 +346,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
reverse_iterator rend()
{ return force<reverse_iterator>(m_flat_tree.rend()); }
{ return container_detail::force<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -337,7 +355,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator rend() const
{ return force<const_reverse_iterator>(m_flat_tree.rend()); }
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -346,7 +364,7 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator crend() const
{ return force<const_reverse_iterator>(m_flat_tree.crend()); }
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.crend()); }
//! <b>Effects</b>: Returns true if the container contains no elements.
//!
@@ -372,20 +390,14 @@ class flat_map
size_type max_size() const
{ return m_flat_tree.max_size(); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Effects: If there is no key equivalent to x in the flat_map, inserts
//! value_type(x, T()) into the flat_map.
//!
//! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
T &operator[](const key_type& k)
{
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first))
i = insert(i, value_type(k, T()));
return (*i).second;
}
mapped_type &operator[](const key_type& k);
//! Effects: If there is no key equivalent to x in the flat_map, inserts
//! value_type(move(x), T()) into the flat_map (the key is move-constructed)
@@ -393,15 +405,11 @@ class flat_map
//! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
T &operator[](BOOST_RV_REF(key_type) mk)
{
key_type &k = mk;
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first))
i = insert(i, value_type(boost::move(k), boost::move(T())));
return (*i).second;
}
mapped_type &operator[](key_type &&k) ;
#else
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, priv_subscript)
#endif
//! Returns: A reference to the element whose key is equivalent to x.
//! Throws: An exception object of type out_of_range if no such element is present.
@@ -448,8 +456,8 @@ class flat_map
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
std::pair<iterator,bool> insert(const value_type& x)
{ return force<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(force<impl_value_type>(x))); }
{ return container_detail::force<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
//! only if there is no element in the container with key equivalent to the key of x.
@@ -463,8 +471,8 @@ class flat_map
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{ return force<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(boost::move(force<impl_value_type>(x)))); }
{ return container_detail::force<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(boost::move(container_detail::force<impl_value_type>(x)))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
//! only if there is no element in the container with key equivalent to the key of x.
@@ -479,7 +487,7 @@ class flat_map
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
std::pair<iterator,bool> insert(BOOST_RV_REF(impl_value_type) x)
{
return force<std::pair<iterator,bool> >
return container_detail::force<std::pair<iterator,bool> >
(m_flat_tree.insert_unique(boost::move(x)));
}
@@ -495,8 +503,8 @@ class flat_map
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const_iterator position, const value_type& x)
{ return force_copy<iterator>(
m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
{ return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts an element move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -508,8 +516,8 @@ class flat_map
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
{ return force_copy<iterator>(
m_flat_tree.insert_unique(force<impl_const_iterator>(position), boost::move(force<impl_value_type>(x)))); }
{ return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(container_detail::force<impl_value_type>(x)))); }
//! <b>Effects</b>: Inserts an element move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -522,8 +530,8 @@ class flat_map
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
{
return force_copy<iterator>(
m_flat_tree.insert_unique(force<impl_const_iterator>(position), boost::move(x)));
return container_detail::force_copy<iterator>(
m_flat_tree.insert_unique(container_detail::force<impl_const_iterator>(position), boost::move(x)));
}
//! <b>Requires</b>: first, last are not iterators into *this.
@@ -539,7 +547,7 @@ class flat_map
void insert(InputIterator first, InputIterator last)
{ m_flat_tree.insert_unique(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container
@@ -555,7 +563,7 @@ class flat_map
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
template <class... Args>
iterator emplace(Args&&... args)
{ return force_copy<iterator>(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container if and only if there is
@@ -571,36 +579,27 @@ class flat_map
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint), boost::forward<Args>(args)...)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique(container_detail::force<impl_const_iterator>(hint), boost::forward<Args>(args)...)); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return force_copy<iterator>(m_flat_tree.emplace_unique()); }
iterator emplace_hint(const_iterator hint)
{ return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint))); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
return force_copy<iterator>(m_flat_tree.emplace_unique \
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
return force_copy<iterator>(m_flat_tree.emplace_hint_unique \
(force<impl_const_iterator>(hint), \
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
} \
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_unique \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \
(container_detail::force<impl_const_iterator>(hint) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by position.
//!
@@ -613,7 +612,7 @@ class flat_map
//! <b>Note</b>: Invalidates elements with keys
//! not less than the erased element.
iterator erase(const_iterator position)
{ return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(position))); }
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//!
@@ -633,7 +632,7 @@ class flat_map
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
iterator erase(const_iterator first, const_iterator last)
{ return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); }
//! <b>Effects</b>: erase(a.begin(),a.end()).
//!
@@ -657,14 +656,14 @@ class flat_map
//!
//! <b>Complexity</b>: Logarithmic.
iterator find(const key_type& x)
{ return force_copy<iterator>(m_flat_tree.find(x)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: A const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.s
const_iterator find(const key_type& x) const
{ return force<const_iterator>(m_flat_tree.find(x)); }
{ return container_detail::force<const_iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
@@ -677,40 +676,40 @@ class flat_map
//!
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x)
{ return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const
{ return force<const_iterator>(m_flat_tree.lower_bound(x)); }
{ return container_detail::force<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x)
{ return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const
{ return force<const_iterator>(m_flat_tree.upper_bound(x)); }
{ return container_detail::force<const_iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
{ return force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
{ return force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -740,6 +739,29 @@ class flat_map
template <class K1, class T1, class C1, class A1>
friend bool operator< (const flat_map<K1, T1, C1, A1>&,
const flat_map<K1, T1, C1, A1>&);
private:
mapped_type &priv_subscript(const key_type& k)
{
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first)){
container_detail::value_init<mapped_type> m;
i = insert(i, impl_value_type(k, ::boost::move(m.m_t)));
}
return (*i).second;
}
mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk)
{
key_type &k = mk;
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first)){
container_detail::value_init<mapped_type> m;
i = insert(i, impl_value_type(boost::move(k), ::boost::move(m.m_t)));
}
return (*i).second;
}
/// @endcond
};
@@ -833,18 +855,18 @@ class flat_multimap
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
typedef containers_detail::flat_tree<Key,
typedef container_detail::flat_tree<Key,
std::pair<Key, T>,
containers_detail::select1st< std::pair<Key, T> >,
container_detail::select1st< std::pair<Key, T> >,
Pred,
A> tree_t;
//This is the real tree stored here. It's based on a movable pair
typedef containers_detail::flat_tree<Key,
containers_detail::pair<Key, T>,
containers_detail::select1st<containers_detail::pair<Key, T> >,
typedef container_detail::flat_tree<Key,
container_detail::pair<Key, T>,
container_detail::select1st<container_detail::pair<Key, T> >,
Pred,
typename A::template
rebind<containers_detail::pair<Key, T> >::other> impl_tree_t;
typename allocator_traits<A>::template portable_rebind_alloc
<container_detail::pair<Key, T> >::type> impl_tree_t;
impl_tree_t m_flat_tree; // flat tree representing flat_map
typedef typename impl_tree_t::value_type impl_value_type;
@@ -858,56 +880,55 @@ class flat_multimap
typedef typename impl_tree_t::reverse_iterator impl_reverse_iterator;
typedef typename impl_tree_t::const_reverse_iterator impl_const_reverse_iterator;
typedef typename impl_tree_t::allocator_type impl_allocator_type;
typedef allocator_traits<A> allocator_traits_type;
template<class D, class S>
static D &force(const S &s)
{ return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
template<class D, class S>
static D force_copy(S s)
{
value_type *vp = reinterpret_cast<value_type *>(&*s);
return D(vp);
}
/// @endcond
public:
// typedefs:
typedef typename impl_tree_t::key_type key_type;
typedef T mapped_type;
typedef typename std::pair<key_type, mapped_type> value_type;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef containers_detail::flat_tree_value_compare
typedef Key key_type;
typedef T mapped_type;
typedef Pred key_compare;
typedef typename std::pair<key_type, mapped_type> value_type;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::const_pointer const_pointer;
typedef typename allocator_traits_type::reference reference;
typedef typename allocator_traits_type::const_reference const_reference;
typedef typename impl_tree_t::size_type size_type;
typedef typename impl_tree_t::difference_type difference_type;
typedef container_detail::flat_tree_value_compare
< Pred
, containers_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare;
typedef Pred key_compare;
typedef typename containers_detail::
get_flat_tree_iterators<pointer>::iterator iterator;
typedef typename containers_detail::
get_flat_tree_iterators<pointer>::const_iterator const_iterator;
typedef typename containers_detail::
, container_detail::select1st< std::pair<Key, T> >
, std::pair<Key, T> > value_compare;
typedef typename container_detail::
get_flat_tree_iterators<pointer>::iterator iterator;
typedef typename container_detail::
get_flat_tree_iterators<pointer>::const_iterator const_iterator;
typedef typename container_detail::
get_flat_tree_iterators
<pointer>::reverse_iterator reverse_iterator;
typedef typename containers_detail::
<pointer>::reverse_iterator reverse_iterator;
typedef typename container_detail::
get_flat_tree_iterators
<pointer>::const_reverse_iterator const_reverse_iterator;
typedef typename impl_tree_t::size_type size_type;
typedef typename impl_tree_t::difference_type difference_type;
typedef A allocator_type;
typedef A stored_allocator_type;
<pointer>::const_reverse_iterator const_reverse_iterator;
typedef A allocator_type;
//Non-standard extension
typedef A stored_allocator_type;
//! <b>Effects</b>: Default constructs an empty flat_map.
//!
//! <b>Complexity</b>: Constant.
flat_multimap()
: m_flat_tree() {}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison
//! object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit flat_multimap(const Pred& comp = Pred(),
explicit flat_multimap(const Pred& comp,
const allocator_type& a = allocator_type())
: m_flat_tree(comp, force<impl_allocator_type>(a)) { }
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a)) { }
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object
//! and allocator, and inserts elements from the range [first ,last ).
@@ -918,7 +939,7 @@ class flat_multimap
flat_multimap(InputIterator first, InputIterator last,
const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
: m_flat_tree(comp, force<impl_allocator_type>(a))
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{ m_flat_tree.insert_equal(first, last); }
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
@@ -967,27 +988,27 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
key_compare key_comp() const
{ return force<key_compare>(m_flat_tree.key_comp()); }
{ return container_detail::force<key_compare>(m_flat_tree.key_comp()); }
//! <b>Effects</b>: Returns an object of value_compare constructed out
//! of the comparison object.
//!
//! <b>Complexity</b>: Constant.
value_compare value_comp() const
{ return value_compare(force<key_compare>(m_flat_tree.key_comp())); }
{ return value_compare(container_detail::force<key_compare>(m_flat_tree.key_comp())); }
//! <b>Effects</b>: Returns a copy of the Allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const
{ return force<allocator_type>(m_flat_tree.get_allocator()); }
{ return container_detail::force<allocator_type>(m_flat_tree.get_allocator()); }
const stored_allocator_type &get_stored_allocator() const
{ return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
stored_allocator_type &get_stored_allocator()
{ return force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the container.
//!
@@ -995,7 +1016,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
iterator begin()
{ return force_copy<iterator>(m_flat_tree.begin()); }
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
@@ -1003,7 +1024,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
const_iterator begin() const
{ return force<const_iterator>(m_flat_tree.begin()); }
{ return container_detail::force<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
//!
@@ -1011,7 +1032,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
iterator end()
{ return force_copy<iterator>(m_flat_tree.end()); }
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
@@ -1019,7 +1040,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
const_iterator end() const
{ return force<const_iterator>(m_flat_tree.end()); }
{ return container_detail::force<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -1028,7 +1049,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
reverse_iterator rbegin()
{ return force<reverse_iterator>(m_flat_tree.rbegin()); }
{ return container_detail::force<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -1037,7 +1058,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator rbegin() const
{ return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
//! of the reversed container.
@@ -1046,7 +1067,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
reverse_iterator rend()
{ return force<reverse_iterator>(m_flat_tree.rend()); }
{ return container_detail::force<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -1055,7 +1076,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator rend() const
{ return force<const_reverse_iterator>(m_flat_tree.rend()); }
{ return container_detail::force<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns true if the container contains no elements.
//!
@@ -1098,7 +1119,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const value_type& x)
{ return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_value_type>(x))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns
//! the iterator pointing to the newly inserted element.
@@ -1108,7 +1129,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(BOOST_RV_REF(value_type) x)
{ return force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
//! <b>Effects</b>: Inserts a new value move-constructed from x and returns
//! the iterator pointing to the newly inserted element.
@@ -1118,7 +1139,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(BOOST_RV_REF(impl_value_type) x)
{ return force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(boost::move(x))); }
//! <b>Effects</b>: Inserts a copy of x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -1132,7 +1153,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const_iterator position, const value_type& x)
{ return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position), container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a value move constructed from x in the container.
//! p is a hint pointing to where the insert should start to search.
@@ -1147,8 +1168,8 @@ class flat_multimap
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
{
return force_copy<iterator>
(m_flat_tree.insert_equal(force<impl_const_iterator>(position)
return container_detail::force_copy<iterator>
(m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position)
, boost::move(x)));
}
@@ -1165,8 +1186,8 @@ class flat_multimap
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
{
return force_copy<iterator>(
m_flat_tree.insert_equal(force<impl_const_iterator>(position), boost::move(x)));
return container_detail::force_copy<iterator>(
m_flat_tree.insert_equal(container_detail::force<impl_const_iterator>(position), boost::move(x)));
}
//! <b>Requires</b>: first, last are not iterators into *this.
@@ -1181,7 +1202,7 @@ class flat_multimap
void insert(InputIterator first, InputIterator last)
{ m_flat_tree.insert_equal(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1193,7 +1214,7 @@ class flat_multimap
//! <b>Note</b>: If an element it's inserted it might invalidate elements.
template <class... Args>
iterator emplace(Args&&... args)
{ return force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container.
@@ -1210,38 +1231,29 @@ class flat_multimap
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return force_copy<iterator>(m_flat_tree.emplace_hint_equal
(force<impl_const_iterator>(hint), boost::forward<Args>(args)...));
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
(container_detail::force<impl_const_iterator>(hint), boost::forward<Args>(args)...));
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return force_copy<iterator>(m_flat_tree.emplace_equal()); }
iterator emplace_hint(const_iterator hint)
{ return force_copy<iterator>(m_flat_tree.emplace_hint_equal(force<impl_const_iterator>(hint))); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
return force_copy<iterator>(m_flat_tree.emplace_equal \
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ \
return force_copy<iterator>(m_flat_tree.emplace_hint_equal \
(force<impl_const_iterator>(hint), \
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _))); \
} \
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal \
(container_detail::force<impl_const_iterator>(hint) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by position.
//!
@@ -1254,7 +1266,7 @@ class flat_multimap
//! <b>Note</b>: Invalidates elements with keys
//! not less than the erased element.
iterator erase(const_iterator position)
{ return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(position))); }
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//!
@@ -1274,7 +1286,7 @@ class flat_multimap
//! <b>Complexity</b>: Logarithmic search time plus erasure time
//! linear to the elements with bigger keys.
iterator erase(const_iterator first, const_iterator last)
{ return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
{ return container_detail::force_copy<iterator>(m_flat_tree.erase(container_detail::force<impl_const_iterator>(first), container_detail::force<impl_const_iterator>(last))); }
//! <b>Effects</b>: erase(a.begin(),a.end()).
//!
@@ -1298,14 +1310,14 @@ class flat_multimap
//!
//! <b>Complexity</b>: Logarithmic.
iterator find(const key_type& x)
{ return force_copy<iterator>(m_flat_tree.find(x)); }
{ return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: An const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
const_iterator find(const key_type& x) const
{ return force<const_iterator>(m_flat_tree.find(x)); }
{ return container_detail::force<const_iterator>(m_flat_tree.find(x)); }
//! <b>Returns</b>: The number of elements with key equivalent to x.
//!
@@ -1318,41 +1330,41 @@ class flat_multimap
//!
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x)
{return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
{return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key
//! not less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const
{ return force<const_iterator>(m_flat_tree.lower_bound(x)); }
{ return container_detail::force<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x)
{return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
{return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Returns</b>: A const iterator pointing to the first element with key
//! not less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const
{ return force<const_iterator>(m_flat_tree.upper_bound(x)); }
{ return container_detail::force<const_iterator>(m_flat_tree.upper_bound(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<iterator,iterator> equal_range(const key_type& x)
{ return force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
//!
//! <b>Complexity</b>: Logarithmic
std::pair<const_iterator,const_iterator>
equal_range(const key_type& x) const
{ return force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -1440,4 +1452,4 @@ struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T,
#include <boost/container/detail/config_end.hpp>
#endif /* BOOST_CONTAINERS_FLAT_MAP_HPP */
#endif /* BOOST_CONTAINER_FLAT_MAP_HPP */

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_FLAT_SET_HPP
#define BOOST_CONTAINERS_FLAT_SET_HPP
#ifndef BOOST_CONTAINER_FLAT_SET_HPP
#define BOOST_CONTAINER_FLAT_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -74,9 +74,9 @@ class flat_set
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(flat_set)
typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, A> tree_t;
typedef container_detail::flat_tree<T, T, container_detail::identity<T>, Pred, A> tree_t;
tree_t m_flat_tree; // flat tree representing flat_set
typedef typename containers_detail::
typedef typename container_detail::
move_const_ref_type<T>::type insert_const_ref_type;
/// @endcond
@@ -100,11 +100,18 @@ 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>Complexity</b>: Constant.
explicit flat_set()
: m_flat_tree()
{}
//! <b>Effects</b>: Constructs an empty flat_map using the specified
//! comparison object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit flat_set(const Pred& comp = Pred(),
explicit flat_set(const Pred& comp,
const allocator_type& a = allocator_type())
: m_flat_tree(comp, a)
{}
@@ -344,7 +351,7 @@ class flat_set
{ return this->insert(const_cast<const T &>(x)); }
template<class U>
std::pair<iterator, bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
std::pair<iterator, bool> insert(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(u); }
#endif
@@ -381,7 +388,7 @@ class flat_set
{ return this->insert(position, const_cast<const T &>(x)); }
template<class U>
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); }
#endif
@@ -410,7 +417,7 @@ class flat_set
void insert(InputIterator first, InputIterator last)
{ m_flat_tree.insert_unique(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container
@@ -444,27 +451,23 @@ class flat_set
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return m_flat_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return m_flat_tree.emplace_unique(); }
iterator emplace_hint(const_iterator hint)
{ return m_flat_tree.emplace_hint_unique(hint); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_hint_unique \
(hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by position.
//!
@@ -702,9 +705,9 @@ class flat_multiset
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, A> tree_t;
typedef container_detail::flat_tree<T, T, container_detail::identity<T>, Pred, A> tree_t;
tree_t m_flat_tree; // flat tree representing flat_multiset
typedef typename containers_detail::
typedef typename container_detail::
move_const_ref_type<T>::type insert_const_ref_type;
/// @endcond
@@ -727,8 +730,14 @@ class flat_multiset
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
// allocation/deallocation
explicit flat_multiset(const Pred& comp = Pred(),
//! <b>Effects</b>: Defatuls constructs an empty flat_map.
//!
//! <b>Complexity</b>: Constant.
explicit flat_multiset()
: m_flat_tree()
{}
explicit flat_multiset(const Pred& comp,
const allocator_type& a = allocator_type())
: m_flat_tree(comp, a) {}
@@ -943,7 +952,7 @@ class flat_multiset
{ return this->insert(const_cast<const T &>(x)); }
template<class U>
iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(u); }
#endif
@@ -975,7 +984,7 @@ class flat_multiset
{ return this->insert(position, const_cast<const T &>(x)); }
template<class U>
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); }
#endif
@@ -1004,7 +1013,7 @@ class flat_multiset
void insert(InputIterator first, InputIterator last)
{ m_flat_tree.insert_equal(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1033,27 +1042,23 @@ class flat_multiset
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return m_flat_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return m_flat_tree.emplace_equal(); }
iterator emplace_hint(const_iterator hint)
{ return m_flat_tree.emplace_hint_equal(hint); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_flat_tree.emplace_hint_equal \
(hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by position.
//!
@@ -1258,4 +1263,4 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
#endif /* BOOST_CONTAINERS_FLAT_SET_HPP */
#endif /* BOOST_CONTAINER_FLAT_SET_HPP */

View File

@@ -7,8 +7,8 @@
// See http://www.boost.org/libs/container for documentation.
//
#ifndef BOOST_CONTAINERS_LIST_HPP_
#define BOOST_CONTAINERS_LIST_HPP_
#ifndef BOOST_CONTAINER_LIST_HPP_
#define BOOST_CONTAINER_LIST_HPP_
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -20,15 +20,16 @@
#include <boost/container/detail/version_type.hpp>
#include <boost/move/move.hpp>
#include <boost/move/move_helpers.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#else
//Preprocessor library to emulate perfect forwarding
#include <boost/container/detail/preprocessor.hpp>
@@ -51,13 +52,13 @@ namespace container {
#endif
/// @cond
namespace containers_detail {
namespace container_detail {
template<class VoidPointer>
struct list_hook
{
typedef typename containers_detail::bi::make_list_base_hook
<containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
typedef typename container_detail::bi::make_list_base_hook
<container_detail::bi::void_pointer<VoidPointer>, container_detail::bi::link_mode<container_detail::bi::normal_link> >::type type;
};
template <class T, class VoidPointer>
@@ -65,33 +66,28 @@ struct list_node
: public list_hook<VoidPointer>::type
{
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
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_CONTAINERS_PERFECT_FORWARDING
list_node()
: m_data()
{}
#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_CONTAINERS_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
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_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
T m_data;
};
@@ -99,21 +95,25 @@ struct list_node
template<class A>
struct intrusive_list_type
{
typedef typename A::value_type value_type;
typedef typename boost::pointer_to_other
<typename A::pointer, void>::type void_pointer;
typedef typename containers_detail::list_node
typedef boost::container::allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::template
rebind_pointer<void>::type
void_pointer;
typedef typename container_detail::list_node
<value_type, void_pointer> node_type;
typedef typename containers_detail::bi::make_list
typedef typename container_detail::bi::make_list
< node_type
, containers_detail::bi::base_hook<typename list_hook<void_pointer>::type>
, containers_detail::bi::constant_time_size<true>
, containers_detail::bi::size_type<typename A::size_type>
, container_detail::bi::base_hook<typename list_hook<void_pointer>::type>
, container_detail::bi::constant_time_size<true>
, container_detail::bi::size_type
<typename allocator_traits_type::size_type>
>::type container_type;
typedef container_type type ;
};
} //namespace containers_detail {
} //namespace container_detail {
/// @endcond
//! A list is a doubly linked list. That is, it is a Sequence that supports both
@@ -132,22 +132,23 @@ template <class T, class A = std::allocator<T> >
template <class T, class A>
#endif
class list
: protected containers_detail::node_alloc_holder
<A, typename containers_detail::intrusive_list_type<A>::type>
: protected container_detail::node_alloc_holder
<A, typename container_detail::intrusive_list_type<A>::type>
{
/// @cond
typedef typename
containers_detail::intrusive_list_type<A>::type Icont;
container_detail::intrusive_list_type<A>::type Icont;
typedef list <T, A> ThisType;
typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<A> allocator_traits_type;
class equal_to_value
{
@@ -181,23 +182,23 @@ class list
public:
//! The type of object, T, stored in the list
typedef T value_type;
typedef T value_type;
//! Pointer to T
typedef typename A::pointer pointer;
typedef typename allocator_traits_type::pointer pointer;
//! Const pointer to T
typedef typename A::const_pointer const_pointer;
typedef typename allocator_traits_type::const_pointer const_pointer;
//! Reference to T
typedef typename A::reference reference;
typedef typename allocator_traits_type::reference reference;
//! Const reference to T
typedef typename A::const_reference const_reference;
typedef typename allocator_traits_type::const_reference const_reference;
//! An unsigned integral type
typedef typename A::size_type size_type;
typedef typename allocator_traits_type::size_type size_type;
//! A signed integral type
typedef typename A::difference_type difference_type;
typedef typename allocator_traits_type::difference_type difference_type;
//! The allocator type
typedef A allocator_type;
//! The stored allocator type
typedef NodeAlloc stored_allocator_type;
typedef A allocator_type;
//! Non-standard extension: the stored allocator type
typedef NodeAlloc stored_allocator_type;
/// @cond
private:
@@ -313,12 +314,21 @@ class list
//! Const iterator used to iterate backwards through a list.
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
//! <b>Effects</b>: Default constructs a list.
//!
//! <b>Throws</b>: If allocator_type's default constructor throws.
//!
//! <b>Complexity</b>: Constant.
list()
: AllocHolder()
{}
//! <b>Effects</b>: Constructs a list taking the allocator as parameter.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
explicit list(const allocator_type &a = A())
explicit list(const allocator_type &a)
: AllocHolder(a)
{}
@@ -329,7 +339,7 @@ class list
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
list(size_type n)
explicit list(size_type n)
: AllocHolder(A())
{ this->resize(n); }
@@ -533,7 +543,6 @@ class list
size_type max_size() const
{ return AllocHolder::max_size(); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
//!
@@ -711,7 +720,15 @@ class list
//! <b>Complexity</b>: Linear to the number of elements in x.
ThisType& operator=(BOOST_COPY_ASSIGN_REF(ThisType) x)
{
if (this != &x) {
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
const NodeAlloc &x_alloc = x.node_alloc();
container_detail::bool_<allocator_traits_type::
propagate_on_container_copy_assignment::value> flag;
if(flag && this_alloc != x_alloc){
this->clear();
}
this->AllocHolder::copy_assign_alloc(x);
this->assign(x.begin(), x.end());
}
return *this;
@@ -725,10 +742,26 @@ class list
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
ThisType& operator=(BOOST_RV_REF(ThisType) mx)
ThisType& operator=(BOOST_RV_REF(ThisType) x)
{
this->clear();
this->swap(mx);
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
NodeAlloc &x_alloc = x.node_alloc();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy and swap pointers
this->clear();
this->icont() = boost::move(x.icont());
//Move allocator if needed
this->AllocHolder::move_assign_alloc(x);
}
//If unequal allocators, then do a one by one move
else{
typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
this->assign( boost::make_move_iterator(x.begin())
, boost::make_move_iterator(x.end()));
}
}
return *this;
}
@@ -753,8 +786,8 @@ class list
template <class InpIt>
void insert(const_iterator p, InpIt first, InpIt last)
{
const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
this->priv_insert_dispatch(p, first, last, Result());
}
@@ -780,7 +813,7 @@ class list
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
#endif
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the list.
@@ -818,57 +851,40 @@ class list
template <class... Args>
iterator emplace(const_iterator p, Args&&... args)
{
typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
new ((void*)containers_detail::get_pointer(d.get())) Node(boost::forward<Args>(args)...);
NodePtr node = d.get();
d.release();
return iterator(this->icont().insert(p.get(), *node));
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert(p.get(), *pnode));
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
//0 args
void emplace_back()
{ this->emplace(this->cend()); }
void emplace_front()
{ this->emplace(this->cbegin()); }
iterator emplace(const_iterator p)
{
typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
new ((void*)containers_detail::get_pointer(d.get())) Node();
NodePtr node = d.get();
d.release();
return iterator(this->icont().insert(p.get(), *node));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
this->emplace(this->cend(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
this->emplace(this->cend() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ this->emplace(this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
new ((void*)containers_detail::get_pointer(d.get())) \
Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
NodePtr node = d.get(); \
d.release(); \
return iterator(this->icont().insert(p.get(), *node)); \
this->emplace(this->cbegin() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr pnode (AllocHolder::create_node \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert(p.get(), *pnode)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
@@ -907,8 +923,8 @@ class list
template <class InpIt>
void assign(InpIt first, InpIt last)
{
const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
this->priv_assign_dispatch(first, last, Result());
}
@@ -925,14 +941,10 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, ThisType& x)
void splice(const_iterator p, ThisType& x) BOOST_CONTAINER_NOEXCEPT
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
this->icont().splice(p.get(), x.icont());
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
}
BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
this->icont().splice(p.get(), x.icont());
}
//! <b>Requires</b>: p must point to an element contained
@@ -949,14 +961,10 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, ThisType &x, const_iterator i)
void splice(const_iterator p, ThisType &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
this->icont().splice(p.get(), x.icont(), i.get());
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
}
BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
this->icont().splice(p.get(), x.icont(), i.get());
}
//! <b>Requires</b>: p must point to an element contained
@@ -972,14 +980,10 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last)
void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
}
BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
}
//! <b>Requires</b>: p must point to an element contained
@@ -996,14 +1000,10 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n)
void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
}
BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
}
//! <b>Effects</b>: Reverses the order of elements in the list.
@@ -1240,11 +1240,11 @@ class list
template <class InputIter>
void priv_insert_dispatch(const_iterator p,
InputIter first, InputIter last,
containers_detail::false_)
container_detail::false_)
{ this->priv_create_and_insert_nodes(p, first, last); }
template<class Integer>
void priv_insert_dispatch(const_iterator p, Integer n, Integer x, containers_detail::true_)
void priv_insert_dispatch(const_iterator p, Integer n, Integer x, container_detail::true_)
{ this->insert(p, (size_type)n, x); }
void priv_fill_assign(size_type n, const T& val)
@@ -1262,11 +1262,11 @@ class list
}
template <class Integer>
void priv_assign_dispatch(Integer n, Integer val, containers_detail::true_)
void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
{ this->priv_fill_assign((size_type) n, (T) val); }
template <class InputIter>
void priv_assign_dispatch(InputIter first2, InputIter last2, containers_detail::false_)
void priv_assign_dispatch(InputIter first2, InputIter last2, container_detail::false_)
{
iterator first1 = this->begin();
iterator last1 = this->end();
@@ -1370,4 +1370,4 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINERS_LIST_HPP_
#endif // BOOST_CONTAINER_LIST_HPP_

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_MAP_HPP
#define BOOST_CONTAINERS_MAP_HPP
#ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -31,7 +31,10 @@
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/move.hpp>
#include <boost/move/move_helpers.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/value_init.hpp>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
@@ -74,9 +77,9 @@ class map
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(map)
typedef containers_detail::rbtree<Key,
typedef container_detail::rbtree<Key,
std::pair<const Key, T>,
containers_detail::select1st< std::pair<const Key, T> >,
container_detail::select1st< std::pair<const Key, T> >,
Pred,
A> tree_t;
tree_t m_tree; // red-black tree representing map
@@ -103,7 +106,7 @@ class map
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
typedef std::pair<key_type, mapped_type> nonconst_value_type;
typedef containers_detail::pair
typedef container_detail::pair
<key_type, mapped_type> nonconst_impl_value_type;
/// @cond
@@ -122,16 +125,26 @@ class map
/// @endcond
typedef value_compare_impl value_compare;
//! <b>Effects</b>: Default constructs an empty map.
//!
//! <b>Complexity</b>: Constant.
map()
: 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));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object
//! and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit map(const Pred& comp = Pred(),
explicit map(const Pred& comp,
const allocator_type& a = allocator_type())
: m_tree(comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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
@@ -145,7 +158,7 @@ class map
: m_tree(first, last, comp, a, true)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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
@@ -162,7 +175,7 @@ class map
: m_tree(ordered_range, first, last, comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
}
//! <b>Effects</b>: Copy constructs a map.
@@ -172,7 +185,7 @@ class map
: m_tree(x.m_tree)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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.
@@ -184,7 +197,7 @@ class map
: m_tree(boost::move(x.m_tree))
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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.
@@ -318,24 +331,14 @@ class map
size_type max_size() const
{ return m_tree.max_size(); }
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! Effects: If there is no key equivalent to x in the map, inserts
//! value_type(x, T()) into the map.
//!
//! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
T& operator[](const key_type& k)
{
//we can optimize this
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first)){
containers_detail::value_init<T> v;
value_type val(k, boost::move(v.m_t));
i = insert(i, boost::move(val));
}
return (*i).second;
}
mapped_type& operator[](const key_type &k);
//! Effects: If there is no key equivalent to x in the map, inserts
//! value_type(boost::move(x), T()) into the map (the key is move-constructed)
@@ -343,18 +346,10 @@ class map
//! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
T& operator[](BOOST_RV_REF(key_type) mk)
{
key_type &k = mk;
//we can optimize this
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first)){
value_type val(boost::move(k), boost::move(T()));
i = insert(i, boost::move(val));
}
return (*i).second;
}
mapped_type& operator[](key_type &&k);
#else
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, priv_subscript)
#endif
//! Returns: A reference to the element whose key is equivalent to x.
//! Throws: An exception object of type out_of_range if no such element is present.
@@ -508,7 +503,7 @@ class map
void insert(InputIterator first, InputIterator last)
{ m_tree.insert_unique(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container if and only if there is
@@ -538,27 +533,23 @@ class map
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return m_tree.emplace_unique(); }
iterator emplace_hint(const_iterator hint)
{ return m_tree.emplace_hint_unique(hint); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_unique(hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by position.
//!
@@ -660,7 +651,35 @@ class map
const map<K1, T1, C1, A1>&);
template <class K1, class T1, class C1, class A1>
friend bool operator< (const map<K1, T1, C1, A1>&,
const map<K1, T1, C1, A1>&);
const map<K1, T1, C1, A1>&);
private:
mapped_type& priv_subscript(const key_type &k)
{
//we can optimize this
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first)){
container_detail::value_init<mapped_type> m;
nonconst_impl_value_type val(k, boost::move(m.m_t));
i = insert(i, boost::move(val));
}
return (*i).second;
}
mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk)
{
key_type &k = mk;
//we can optimize this
iterator i = lower_bound(k);
// i->first is greater than or equivalent to k.
if (i == end() || key_comp()(k, (*i).first)){
container_detail::value_init<mapped_type> m;
nonconst_impl_value_type val(boost::move(k), boost::move(m.m_t));
i = insert(i, boost::move(val));
}
return (*i).second;
}
/// @endcond
};
@@ -747,12 +766,14 @@ class multimap
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(multimap)
typedef containers_detail::rbtree<Key,
typedef container_detail::rbtree<Key,
std::pair<const Key, T>,
containers_detail::select1st< std::pair<const Key, T> >,
container_detail::select1st< std::pair<const Key, T> >,
Pred,
A> tree_t;
tree_t m_tree; // red-black tree representing map
typedef typename container_detail::
move_const_ref_type<Key>::type insert_key_const_ref_type;
/// @endcond
public:
@@ -775,7 +796,7 @@ class multimap
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
typedef std::pair<key_type, mapped_type> nonconst_value_type;
typedef containers_detail::pair
typedef container_detail::pair
<key_type, mapped_type> nonconst_impl_value_type;
/// @cond
@@ -794,16 +815,25 @@ class multimap
/// @endcond
typedef value_compare_impl value_compare;
//! <b>Effects</b>: Default constructs an empty multimap.
//!
//! <b>Complexity</b>: Constant.
multimap()
: 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));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison
//! object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit multimap(const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
explicit multimap(const Pred& comp, const allocator_type& a = allocator_type())
: m_tree(comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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
@@ -818,7 +848,7 @@ class multimap
: m_tree(first, last, comp, a, false)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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
@@ -842,7 +872,7 @@ class multimap
: m_tree(x.m_tree)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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.
@@ -854,7 +884,7 @@ class multimap
: m_tree(boost::move(x.m_tree))
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((containers_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
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.
@@ -1078,7 +1108,7 @@ class multimap
void insert(InputIterator first, InputIterator last)
{ m_tree.insert_equal(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container.
@@ -1106,27 +1136,23 @@ class multimap
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return m_tree.emplace_equal(); }
iterator emplace_hint(const_iterator hint)
{ return m_tree.emplace_hint_equal(hint); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_equal(hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by position.
//!
@@ -1288,5 +1314,5 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
#endif /* BOOST_CONTAINERS_MAP_HPP */
#endif /* BOOST_CONTAINER_MAP_HPP */

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_SET_HPP
#define BOOST_CONTAINERS_SET_HPP
#ifndef BOOST_CONTAINER_SET_HPP
#define BOOST_CONTAINER_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -27,7 +27,7 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/tree.hpp>
#include <boost/move/move.hpp>
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -67,10 +67,10 @@ class set
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(set)
typedef containers_detail::rbtree<T, T,
containers_detail::identity<T>, Pred, A> tree_t;
typedef container_detail::rbtree<T, T,
container_detail::identity<T>, Pred, A> tree_t;
tree_t m_tree; // red-black tree representing set
typedef typename containers_detail::
typedef typename container_detail::
move_const_ref_type<T>::type insert_const_ref_type;
/// @endcond
@@ -94,11 +94,18 @@ class set
typedef typename tree_t::allocator_type allocator_type;
typedef typename tree_t::stored_allocator_type stored_allocator_type;
//! <b>Effects</b>: Default constructs an empty set.
//!
//! <b>Complexity</b>: Constant.
set()
: m_tree()
{}
//! <b>Effects</b>: Constructs an empty set using the specified comparison object
//! and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit set(const Pred& comp = Pred(),
explicit set(const Pred& comp,
const allocator_type& a = allocator_type())
: m_tree(comp, a)
{}
@@ -334,7 +341,7 @@ class set
{ return this->insert(const_cast<const T &>(x)); }
template<class U>
std::pair<iterator,bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
std::pair<iterator,bool> insert(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(u); }
#endif
@@ -366,7 +373,7 @@ class set
{ return this->insert(position, const_cast<const T &>(x)); }
template<class U>
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); }
#endif
@@ -389,7 +396,7 @@ class set
void insert(InputIterator first, InputIterator last)
{ m_tree.insert_unique(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... if and only if there is
@@ -418,27 +425,23 @@ class set
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return m_tree.emplace_unique(); }
iterator emplace_hint(const_iterator hint)
{ return m_tree.emplace_hint_unique(hint); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _));}\
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_unique(hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by p.
//!
@@ -629,10 +632,10 @@ class multiset
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(multiset)
typedef containers_detail::rbtree<T, T,
containers_detail::identity<T>, Pred, A> tree_t;
typedef container_detail::rbtree<T, T,
container_detail::identity<T>, Pred, A> tree_t;
tree_t m_tree; // red-black tree representing multiset
typedef typename containers_detail::
typedef typename container_detail::
move_const_ref_type<T>::type insert_const_ref_type;
/// @endcond
@@ -660,7 +663,15 @@ class multiset
//! object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit multiset(const Pred& comp = Pred(),
multiset()
: m_tree()
{}
//! <b>Effects</b>: Constructs an empty multiset using the specified comparison
//! object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit multiset(const Pred& comp,
const allocator_type& a = allocator_type())
: m_tree(comp, a)
{}
@@ -893,7 +904,7 @@ class multiset
{ return this->insert(const_cast<const T &>(x)); }
template<class U>
iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(u); }
#endif
@@ -923,7 +934,7 @@ class multiset
{ return this->insert(position, const_cast<const T &>(x)); }
template<class U>
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_insert(position, u); }
#endif
@@ -947,7 +958,7 @@ class multiset
void insert(InputIterator first, InputIterator last)
{ m_tree.insert_equal(first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -970,27 +981,23 @@ class multiset
iterator emplace_hint(const_iterator hint, Args&&... args)
{ return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
iterator emplace()
{ return m_tree.emplace_equal(); }
iterator emplace_hint(const_iterator hint)
{ return m_tree.emplace_hint_equal(hint); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); } \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); }\
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
\
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ return m_tree.emplace_hint_equal(hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element pointed to by p.
//!
@@ -1159,5 +1166,5 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
#endif /* BOOST_CONTAINERS_SET_HPP */
#endif /* BOOST_CONTAINER_SET_HPP */

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINERS_SLIST_HPP
#define BOOST_CONTAINERS_SLIST_HPP
#ifndef BOOST_CONTAINER_SLIST_HPP
#define BOOST_CONTAINER_SLIST_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -20,7 +20,7 @@
#include <boost/container/container_fwd.hpp>
#include <boost/move/move.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
@@ -29,7 +29,7 @@
#include <boost/intrusive/slist.hpp>
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//Preprocessor library to emulate perfect forwarding
#else
#include <boost/container/detail/preprocessor.hpp>
@@ -52,46 +52,43 @@ namespace container {
/// @cond
namespace containers_detail {
namespace container_detail {
template<class VoidPointer>
struct slist_hook
{
typedef typename containers_detail::bi::make_slist_base_hook
<containers_detail::bi::void_pointer<VoidPointer>, containers_detail::bi::link_mode<containers_detail::bi::normal_link> >::type type;
typedef typename container_detail::bi::make_slist_base_hook
<container_detail::bi::void_pointer<VoidPointer>, container_detail::bi::link_mode<container_detail::bi::normal_link> >::type type;
};
template <class T, class VoidPointer>
struct slist_node
: public slist_hook<VoidPointer>::type
{
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
slist_node()
: m_data()
{}
#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_CONTAINERS_PERFECT_FORWARDING
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
slist_node()
: m_data()
{}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
: m_data(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
{} \
#define BOOST_PP_LOCAL_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_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif//#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
T m_data;
};
@@ -99,22 +96,26 @@ struct slist_node
template<class A>
struct intrusive_slist_type
{
typedef typename A::value_type value_type;
typedef typename boost::pointer_to_other
<typename A::pointer, void>::type void_pointer;
typedef typename containers_detail::slist_node
typedef boost::container::allocator_traits<A> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::template
rebind_pointer<void>::type
void_pointer;
typedef typename container_detail::slist_node
<value_type, void_pointer> node_type;
typedef typename containers_detail::bi::make_slist
typedef typename container_detail::bi::make_slist
<node_type
,containers_detail::bi::base_hook<typename slist_hook<void_pointer>::type>
,containers_detail::bi::constant_time_size<true>
,containers_detail::bi::size_type<typename A::size_type>
,container_detail::bi::base_hook<typename slist_hook<void_pointer>::type>
,container_detail::bi::constant_time_size<true>
, container_detail::bi::size_type
<typename allocator_traits_type::size_type>
>::type container_type;
typedef container_type type ;
};
} //namespace containers_detail {
} //namespace container_detail {
/// @endcond
@@ -156,24 +157,25 @@ template <class T, class A = std::allocator<T> >
template <class T, class A>
#endif
class slist
: protected containers_detail::node_alloc_holder
<A, typename containers_detail::intrusive_slist_type<A>::type>
: protected container_detail::node_alloc_holder
<A, typename container_detail::intrusive_slist_type<A>::type>
{
/// @cond
typedef typename containers_detail::
typedef typename container_detail::
move_const_ref_type<T>::type insert_const_ref_type;
typedef typename
containers_detail::intrusive_slist_type<A>::type Icont;
typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
container_detail::intrusive_slist_type<A>::type Icont;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef slist <T, A> ThisType;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef containers_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<A> allocator_traits_type;
class equal_to_value
{
@@ -206,23 +208,23 @@ class slist
/// @endcond
public:
//! The type of object, T, stored in the list
typedef T value_type;
typedef T value_type;
//! Pointer to T
typedef typename A::pointer pointer;
typedef typename allocator_traits_type::pointer pointer;
//! Const pointer to T
typedef typename A::const_pointer const_pointer;
typedef typename allocator_traits_type::const_pointer const_pointer;
//! Reference to T
typedef typename A::reference reference;
typedef typename allocator_traits_type::reference reference;
//! Const reference to T
typedef typename A::const_reference const_reference;
typedef typename allocator_traits_type::const_reference const_reference;
//! An unsigned integral type
typedef typename A::size_type size_type;
typedef typename allocator_traits_type::size_type size_type;
//! A signed integral type
typedef typename A::difference_type difference_type;
typedef typename allocator_traits_type::difference_type difference_type;
//! The allocator type
typedef A allocator_type;
//! The stored allocator type
typedef NodeAlloc stored_allocator_type;
typedef A allocator_type;
//! Non-standard extension: the stored allocator type
typedef NodeAlloc stored_allocator_type;
/// @cond
private:
@@ -328,7 +330,16 @@ class slist
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
explicit slist(const allocator_type& a = allocator_type())
slist()
: AllocHolder()
{}
//! <b>Effects</b>: Constructs a list taking the allocator as parameter.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
explicit slist(const allocator_type& a)
: AllocHolder(a)
{}
@@ -377,7 +388,7 @@ class slist
//!
//! <b>Complexity</b>: Constant.
slist(BOOST_RV_REF(slist) x)
: AllocHolder(boost::move((AllocHolder&)x))
: AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
{}
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -391,6 +402,14 @@ class slist
slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x)
{
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
const NodeAlloc &x_alloc = x.node_alloc();
container_detail::bool_<allocator_traits_type::
propagate_on_container_copy_assignment::value> flag;
if(flag && this_alloc != x_alloc){
this->clear();
}
this->AllocHolder::copy_assign_alloc(x);
this->assign(x.begin(), x.end());
}
return *this;
@@ -404,11 +423,25 @@ class slist
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the number of elements in x.
slist& operator= (BOOST_RV_REF(slist) mx)
slist& operator= (BOOST_RV_REF(slist) x)
{
if (&mx != this){
this->clear();
this->swap(mx);
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
NodeAlloc &x_alloc = x.node_alloc();
//If allocators a re equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy and swap pointers
this->clear();
this->icont() = boost::move(x.icont());
//Move allocator if needed
this->AllocHolder::move_assign_alloc(x);
}
//If unequal allocators, then do a one by one move
else{
typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
this->assign( boost::make_move_iterator(x.begin())
, boost::make_move_iterator(x.end()));
}
}
return *this;
}
@@ -455,8 +488,8 @@ class slist
template <class InpIt>
void assign(InpIt first, InpIt last)
{
const bool aux_boolean = containers_detail::is_convertible<InpIt, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
this->priv_assign_dispatch(first, last, Result());
}
@@ -607,7 +640,7 @@ class slist
void push_front(T &x) { push_front(const_cast<const T &>(x)); }
template<class U>
void push_front(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
void push_front(const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_push_front(u); }
#endif
@@ -669,7 +702,7 @@ class slist
{ return this->insert_after(position, const_cast<const T &>(x)); }
template<class U>
iterator insert_after(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert_after(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return this->priv_insert_after(position, u); }
#endif
@@ -717,8 +750,8 @@ class slist
template <class InIter>
void insert_after(const_iterator prev_pos, InIter first, InIter last)
{
const bool aux_boolean = containers_detail::is_convertible<InIter, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InIter, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
}
@@ -737,7 +770,7 @@ class slist
{ return this->insert(position, const_cast<const T &>(x)); }
template<class U>
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return this->priv_insert(position, u); }
#endif
@@ -774,7 +807,7 @@ class slist
void insert(const_iterator p, InIter first, InIter last)
{ return this->insert_after(previous(p), first, last); }
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the front of the list
@@ -808,63 +841,42 @@ class slist
template <class... Args>
iterator emplace_after(const_iterator prev, Args&&... args)
{
typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
new ((void*)containers_detail::get_pointer(d.get())) Node(boost::forward<Args>(args)...);
NodePtr node = d.get();
d.release();
return iterator(this->icont().insert_after(prev.get(), *node));
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_after(prev.get(), *pnode));
}
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
//0 args
void emplace_front()
{ this->emplace_after(this->cbefore_begin()); }
iterator emplace(const_iterator p)
{ return this->emplace_after(this->previous(p)); }
iterator emplace_after(const_iterator prev)
{
typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
new ((void*)containers_detail::get_pointer(d.get())) Node();
NodePtr node = d.get();
d.release();
return iterator(this->icont().insert_after(prev.get(), *node));
}
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
this->emplace \
(this->cbegin(), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
this->emplace(this->cbegin() \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace \
(const_iterator p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace (const_iterator p \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
return this->emplace_after \
(this->previous(p), BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
(this->previous(p) \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace_after \
(const_iterator prev, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_after(const_iterator prev \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
new ((void*)containers_detail::get_pointer(d.get())) \
Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
NodePtr node = d.get(); \
d.release(); \
return iterator(this->icont().insert_after(prev.get(), *node)); \
NodePtr pnode (AllocHolder::create_node \
(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_after(prev.get(), *pnode)); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element after the element pointed by prev_pos
//! of the list.
@@ -1337,11 +1349,11 @@ class slist
template <class InputIter>
void priv_insert_dispatch(const_iterator prev,
InputIter first, InputIter last,
containers_detail::false_)
container_detail::false_)
{ this->priv_create_and_insert_nodes(prev, first, last); }
template<class Integer>
void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, containers_detail::true_)
void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, container_detail::true_)
{ this->priv_create_and_insert_nodes(prev, (size_type)n, x); }
void priv_fill_assign(size_type n, const T& val)
@@ -1361,11 +1373,11 @@ class slist
}
template <class Int>
void priv_assign_dispatch(Int n, Int val, containers_detail::true_)
void priv_assign_dispatch(Int n, Int val, container_detail::true_)
{ this->priv_fill_assign((size_type) n, (T)val); }
template <class InpIt>
void priv_assign_dispatch(InpIt first, InpIt last, containers_detail::false_)
void priv_assign_dispatch(InpIt first, InpIt last, container_detail::false_)
{
iterator end_n(this->end());
iterator prev(this->before_begin());
@@ -1383,11 +1395,11 @@ class slist
}
template <class Int>
void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, containers_detail::true_)
void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, container_detail::true_)
{ this->priv_create_and_insert_nodes(prev_pos, (size_type)n, x); }
template <class InIter>
void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, containers_detail::false_)
void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, container_detail::false_)
{ this->priv_create_and_insert_nodes(prev_pos, first, last); }
//Functors for member algorithm defaults
@@ -1533,4 +1545,4 @@ class insert_iterator<boost::container::slist<T, A> >
#include <boost/container/detail/config_end.hpp>
#endif /* BOOST_CONTAINERS_SLIST_HPP */
#endif /* BOOST_CONTAINER_SLIST_HPP */

View File

@@ -27,15 +27,14 @@
#include <boost/container/container_fwd.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/get_pointer.hpp>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <algorithm>
#include <stdexcept>
@@ -79,7 +78,7 @@ struct smart_ptr_type<T*>
};
template<class Ptr>
inline typename smart_ptr_type<Ptr>::pointer get_pointer(const Ptr &ptr)
inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
{ return smart_ptr_type<Ptr>::get(ptr); }
template <class C>
@@ -126,33 +125,29 @@ template<typename VoidPointer, typename T>
struct node_type
: public node_type_base<VoidPointer>
{
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
node_type()
: value()
{}
#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_CONTAINERS_PERFECT_FORWARDING
#else //BOOST_CONTAINER_PERFECT_FORWARDING
node_type()
: value()
{}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
node_type(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
: value(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
{} \
#define BOOST_PP_LOCAL_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_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif//BOOST_CONTAINERS_PERFECT_FORWARDING
#endif//BOOST_CONTAINER_PERFECT_FORWARDING
void set_pointer(VoidPointer p)
{ node_type_base<VoidPointer>::set_pointer(p); }
@@ -163,33 +158,38 @@ struct node_type
template<typename T, typename Reference, typename Pointer>
class iterator
: public std::iterator< std::random_access_iterator_tag
, typename std::iterator_traits<Pointer>::value_type
, typename std::iterator_traits<Pointer>::difference_type
, T
, typename boost::intrusive::
pointer_traits<Pointer>::difference_type
, Pointer
, Reference>
{
typedef typename boost::intrusive::
pointer_traits<Pointer>::template
rebind_pointer<void>::type void_ptr;
typedef typename boost::intrusive::
pointer_traits<Pointer>::template
rebind_pointer<const void>::type const_void_ptr;
typedef node_type<void_ptr, T> node_type_t;
typedef typename boost::intrusive::
pointer_traits<Pointer>::template
rebind_pointer<node_type_t>::type node_type_ptr_t;
typedef typename boost::intrusive::
pointer_traits<Pointer>::template
rebind_pointer<const node_type_t>::type const_node_type_ptr_t;
typedef typename boost::intrusive::
pointer_traits<Pointer>::template
rebind_pointer<void_ptr>::type void_ptr_ptr;
typedef typename boost::pointer_to_other
<Pointer, void>::type void_ptr;
typedef typename boost::pointer_to_other
<Pointer, const void>::type const_void_ptr;
typedef node_type<void_ptr, T> node_type_t;
typedef typename boost::pointer_to_other
<void_ptr, node_type_t>::type node_type_ptr_t;
typedef typename boost::pointer_to_other
<void_ptr, const node_type_t>::type const_node_type_ptr_t;
typedef typename boost::pointer_to_other
<void_ptr, void_ptr>::type void_ptr_ptr;
friend class iterator<T, const T, typename boost::pointer_to_other<Pointer, T>::type>;
friend class iterator<T, const T, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
typedef typename std::iterator_traits
<Pointer>::difference_type difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef std::random_access_iterator_tag iterator_category;
typedef T value_type;
typedef typename boost::intrusive::
pointer_traits<Pointer>::difference_type difference_type;
typedef Pointer pointer;
typedef Reference reference;
iterator()
{}
@@ -198,27 +198,24 @@ class iterator
: pn(pn)
{}
iterator(const iterator<T, T&, typename boost::pointer_to_other<Pointer, T>::type >& x)
iterator(const iterator<T, T&, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>& x)
: pn(x.pn)
{}
private:
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
using boost::get_pointer;
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
}
static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
{
using boost::get_pointer;
return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::get_pointer(p)));
return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
}
static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
{
using boost::get_pointer;
return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::get_pointer(p)));
return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
}
reference dereference() const
@@ -325,12 +322,15 @@ struct select_multiallocation_chain
template<class A>
struct select_multiallocation_chain<A, 1>
{
typedef typename A::template
rebind<void>::other::pointer void_ptr;
typedef containers_detail::basic_multiallocation_chain
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits<A>::pointer>::
template rebind_pointer<void>::type void_ptr;
typedef container_detail::basic_multiallocation_chain
<void_ptr> multialloc_cached_counted;
typedef boost::container::containers_detail::transform_multiallocation_chain
<multialloc_cached_counted, typename A::value_type> type;
typedef boost::container::container_detail::
transform_multiallocation_chain
< multialloc_cached_counted
, typename allocator_traits<A>::value_type> type;
};
} //namespace stable_vector_detail
@@ -389,59 +389,82 @@ template <class T, class A>
class stable_vector
{
///@cond
typedef typename containers_detail::
move_const_ref_type<T>::type insert_const_ref_type;
typedef typename A::template
rebind<void>::other::pointer void_ptr;
typedef typename boost::pointer_to_other
<void_ptr, const void>::type const_void_ptr;
typedef typename A::template
rebind<void_ptr>::other::pointer void_ptr_ptr;
typedef typename boost::pointer_to_other
<void_ptr, const void_ptr>::type const_void_ptr_ptr;
typedef allocator_traits<A> allocator_traits_type;
typedef typename container_detail::
move_const_ref_type<T>::type insert_const_ref_type;
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::
template rebind_pointer<void>::type void_ptr;
typedef typename boost::intrusive::pointer_traits
<void_ptr>::template
rebind_pointer<const void>::type const_void_ptr;
typedef typename boost::intrusive::pointer_traits
<void_ptr>::template
rebind_pointer<void_ptr>::type void_ptr_ptr;
typedef typename boost::intrusive::pointer_traits
<void_ptr>::template
rebind_pointer<const void_ptr>::type const_void_ptr_ptr;
typedef stable_vector_detail::node_type
<void_ptr, T> node_type_t;
typedef typename A::template
rebind<node_type_t>::other::pointer node_type_ptr_t;
typedef typename boost::intrusive::pointer_traits
<void_ptr>::template
rebind_pointer<node_type_t>::type node_type_ptr_t;
typedef stable_vector_detail::node_type_base
<void_ptr> node_type_base_t;
typedef typename A::template
rebind<node_type_base_t>::other::pointer node_type_base_ptr_t;
typedef
::boost::container::vector<void_ptr,
typename A::
template rebind<void_ptr>::other
> impl_type;
typedef typename boost::intrusive::pointer_traits
<void_ptr>::template
rebind_pointer<node_type_base_t>::type node_type_base_ptr_t;
typedef ::boost::container::vector<void_ptr,
typename allocator_traits_type::
template portable_rebind_alloc
<void_ptr>::type> impl_type;
typedef typename impl_type::iterator impl_iterator;
typedef typename impl_type::const_iterator const_impl_iterator;
typedef ::boost::container::containers_detail::
typedef ::boost::container::container_detail::
integral_constant<unsigned, 1> allocator_v1;
typedef ::boost::container::containers_detail::
typedef ::boost::container::container_detail::
integral_constant<unsigned, 2> allocator_v2;
typedef ::boost::container::containers_detail::integral_constant
<unsigned, boost::container::containers_detail::
version<A>::value> alloc_version;
typedef typename A::
template rebind<node_type_t>::other node_allocator_type;
typedef ::boost::container::container_detail::integral_constant
<unsigned, boost::container::container_detail::
version<A>::value> alloc_version;
typedef typename allocator_traits_type::
template portable_rebind_alloc
<node_type_t>::type node_allocator_type;
node_type_ptr_t allocate_one()
{ return this->allocate_one(alloc_version()); }
node_type_ptr_t allocate_one(allocator_v1)
{ return get_al().allocate(1); }
template<class AllocatorVersion>
node_type_ptr_t allocate_one(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ return node_alloc().allocate(1); }
node_type_ptr_t allocate_one(allocator_v2)
{ return get_al().allocate_one(); }
template<class AllocatorVersion>
node_type_ptr_t allocate_one(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
::value>::type * = 0)
{ return node_alloc().allocate_one(); }
void deallocate_one(node_type_ptr_t p)
{ return this->deallocate_one(p, alloc_version()); }
void deallocate_one(node_type_ptr_t p, allocator_v1)
{ get_al().deallocate(p, 1); }
template<class AllocatorVersion>
void deallocate_one(node_type_ptr_t p, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ node_alloc().deallocate(p, 1); }
void deallocate_one(node_type_ptr_t p, allocator_v2)
{ get_al().deallocate_one(p); }
template<class AllocatorVersion>
void deallocate_one(node_type_ptr_t p, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
::value>::type * = 0)
{ node_alloc().deallocate_one(p); }
friend class stable_vector_detail::clear_on_destroy<stable_vector>;
///@endcond
@@ -450,10 +473,10 @@ class stable_vector
// types:
typedef typename A::reference reference;
typedef typename A::const_reference const_reference;
typedef typename A::pointer pointer;
typedef typename A::const_pointer const_pointer;
typedef typename allocator_traits_type::reference reference;
typedef typename allocator_traits_type::const_reference const_reference;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::const_pointer const_pointer;
typedef stable_vector_detail::iterator
<T,T&, pointer> iterator;
typedef stable_vector_detail::iterator
@@ -461,9 +484,10 @@ class stable_vector
typedef typename impl_type::size_type size_type;
typedef typename iterator::difference_type difference_type;
typedef T value_type;
typedef A allocator_type;
typedef A allocator_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef node_allocator_type stored_allocator_type;
///@cond
private:
@@ -483,13 +507,24 @@ class stable_vector
///@endcond
public:
//! <b>Effects</b>: Default constructs a stable_vector.
//!
//! <b>Throws</b>: If allocator_type's default constructor throws.
//!
//! <b>Complexity</b>: Constant.
stable_vector()
: internal_data(), impl()
{
STABLE_VECTOR_CHECK_INVARIANT;
}
//! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
explicit stable_vector(const A& al=A())
: internal_data(al),impl(al)
explicit stable_vector(const A& al)
: internal_data(al),impl(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
}
@@ -502,7 +537,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to n.
explicit stable_vector(size_type n)
: internal_data(A()),impl(A())
: internal_data(A()),impl(A())
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n);
@@ -518,7 +553,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to n.
stable_vector(size_type n, const T& t, const A& al=A())
: internal_data(al),impl(al)
: internal_data(al),impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cbegin(), n, t);
@@ -549,7 +584,10 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to the elements x contains.
stable_vector(const stable_vector& x)
: internal_data(x.get_al()),impl(x.get_al())
: internal_data(allocator_traits<node_allocator_type>::
select_on_container_copy_construction(x.node_alloc()))
, impl(allocator_traits<allocator_type>::
select_on_container_copy_construction(x.impl.get_stored_allocator()))
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cbegin(), x.begin(), x.end());
@@ -562,9 +600,11 @@ class stable_vector
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
stable_vector(BOOST_RV_REF(stable_vector) x)
: internal_data(x.get_al()),impl(x.get_al())
{ this->swap(x); }
stable_vector(BOOST_RV_REF(stable_vector) x)
: internal_data(boost::move(x.node_alloc())), impl(boost::move(x.impl))
{
this->priv_swap_members(x);
}
//! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
//! and used memory is deallocated.
@@ -589,7 +629,17 @@ class stable_vector
stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
{
STABLE_VECTOR_CHECK_INVARIANT;
if (this != &x) {
if (&x != this){
node_allocator_type &this_alloc = this->node_alloc();
const node_allocator_type &x_alloc = x.node_alloc();
container_detail::bool_<allocator_traits_type::
propagate_on_container_copy_assignment::value> flag;
if(flag && this_alloc != x_alloc){
this->clear();
this->shrink_to_fit();
}
container_detail::assign_alloc(this->node_alloc(), x.node_alloc(), flag);
container_detail::assign_alloc(this->impl.get_stored_allocator(), x.impl.get_stored_allocator(), flag);
this->assign(x.begin(), x.end());
}
return *this;
@@ -606,8 +656,25 @@ class stable_vector
stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
{
if (&x != this){
this->swap(x);
x.clear();
node_allocator_type &this_alloc = this->node_alloc();
node_allocator_type &x_alloc = x.node_alloc();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy objects but retain memory
this->clear();
this->impl = boost::move(x.impl);
this->priv_swap_members(x);
//Move allocator if needed
container_detail::bool_<allocator_traits_type::
propagate_on_container_move_assignment::value> flag;
container_detail::move_alloc(this->node_alloc(), x.node_alloc(), flag);
}
//If unequal allocators, then do a one by one move
else{
typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
this->assign( boost::make_move_iterator(x.begin())
, boost::make_move_iterator(x.end()));
}
}
return *this;
}
@@ -641,7 +708,27 @@ class stable_vector
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator()const {return get_al();}
allocator_type get_allocator()const {return node_alloc();}
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return node_alloc(); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
@@ -946,7 +1033,8 @@ class stable_vector
void push_back(T &x) { push_back(const_cast<const T &>(x)); }
template<class U>
void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
void push_back(const U &u, typename container_detail::enable_if_c
<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return priv_push_back(u); }
#endif
@@ -982,7 +1070,8 @@ class stable_vector
iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
template<class U>
iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c
<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
{ return this->priv_insert(position, u); }
#endif
@@ -1035,7 +1124,7 @@ class stable_vector
boost::mpl::not_<boost::is_integral<InputIterator> >());
}
#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the stable_vector.
@@ -1046,7 +1135,7 @@ class stable_vector
template<class ...Args>
void emplace_back(Args &&...args)
{
typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
typedef emplace_functor<Args...> EmplaceFunctor;
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
@@ -1066,7 +1155,7 @@ class stable_vector
{
//Just call more general insert(pos, size, value) and return iterator
size_type pos_n = position - cbegin();
typedef emplace_functor<node_type_t, Args...> EmplaceFunctor;
typedef emplace_functor<Args...> EmplaceFunctor;
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
@@ -1075,51 +1164,40 @@ class stable_vector
#else
void emplace_back()
{
typedef emplace_functor<node_type_t> EmplaceFunctor;
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor ef;
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
}
iterator emplace(const_iterator position)
{
typedef emplace_functor<node_type_t> EmplaceFunctor;
typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
EmplaceFunctor ef;
size_type pos_n = position - this->cbegin();
this->insert(position, EmplaceIterator(ef), EmplaceIterator());
return iterator(this->begin() + pos_n);
}
#define BOOST_PP_LOCAL_MACRO(n) \
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
<node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
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; \
EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
} \
\
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace(const_iterator pos \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
<node_type_t, BOOST_PP_ENUM_PARAMS(n, P)> EmplaceFunctor; \
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; \
EmplaceFunctor ef(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
BOOST_PP_RPAREN_IF(n); \
size_type pos_n = pos - this->cbegin(); \
this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
return iterator(this->begin() + pos_n); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//! <b>Effects</b>: Erases the element at position pos.
//!
@@ -1157,7 +1235,11 @@ class stable_vector
void swap(stable_vector & x)
{
STABLE_VECTOR_CHECK_INVARIANT;
this->swap_impl(*this,x);
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
//vector's allocator is swapped here
this->impl.swap(x.impl);
this->priv_swap_members(x);
}
//! <b>Effects</b>: Erases all the elements of the stable_vector.
@@ -1181,7 +1263,8 @@ class stable_vector
this->clear_pool();
//If empty completely destroy the index, let's recover default-constructed state
if(this->empty()){
impl_type().swap(this->impl);
this->impl.clear();
this->impl.shrink_to_fit();
this->internal_data.set_end_pointer_to_default_constructed();
}
//Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
@@ -1209,7 +1292,11 @@ class stable_vector
void priv_push_back(const value_type &t)
{ this->insert(end(), t); }
void clear_pool(allocator_v1)
template<class AllocatorVersion>
void clear_pool(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{
if(!impl.empty() && impl.back()){
void_ptr &pool_first_ref = impl.end()[-2];
@@ -1227,15 +1314,18 @@ class stable_vector
}
}
void clear_pool(allocator_v2)
template<class AllocatorVersion>
void clear_pool(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
::value>::type * = 0)
{
if(!impl.empty() && impl.back()){
void_ptr &pool_first_ref = impl.end()[-2];
void_ptr &pool_last_ref = impl.back();
multiallocation_chain holder;
holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
get_al().deallocate_individual(boost::move(holder));
node_alloc().deallocate_individual(boost::move(holder));
pool_first_ref = pool_last_ref = 0;
this->internal_data.pool_size = 0;
}
@@ -1251,7 +1341,11 @@ class stable_vector
this->add_to_pool(n, alloc_version());
}
void add_to_pool(size_type n, allocator_v1)
template<class AllocatorVersion>
void add_to_pool(size_type n, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{
size_type remaining = n;
while(remaining--){
@@ -1259,14 +1353,18 @@ class stable_vector
}
}
void add_to_pool(size_type n, allocator_v2)
template<class AllocatorVersion>
void add_to_pool(size_type n, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
::value>::type * = 0)
{
void_ptr &pool_first_ref = impl.end()[-2];
void_ptr &pool_last_ref = impl.back();
multiallocation_chain holder;
holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<multiallocation_chain>::value == true));
multiallocation_chain m (get_al().allocate_individual(n));
multiallocation_chain m (node_alloc().allocate_individual(n));
holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
this->internal_data.pool_size += n;
std::pair<void_ptr, void_ptr> data(holder.extract_data());
@@ -1375,8 +1473,8 @@ class stable_vector
template<class AllocatorVersion>
iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
typename boost::container::containers_detail::enable_if_c
<boost::container::containers_detail::is_same<AllocatorVersion, allocator_v2>
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v2>
::value>::type * = 0)
{
STABLE_VECTOR_CHECK_INVARIANT;
@@ -1385,14 +1483,12 @@ class stable_vector
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
using boost::get_pointer;
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::get_pointer(p)));
return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
}
static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
{
using boost::get_pointer;
return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::get_pointer(p)));
return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
}
static value_type& value(const void_ptr &p)
@@ -1434,7 +1530,7 @@ class stable_vector
{
node_type_ptr_t p = this->allocate_one();
try{
boost::container::construct_in_place(&*p, it);
boost::container::construct_in_place(this->node_alloc(), &*p, it);
p->set_pointer(up);
}
catch(...){
@@ -1516,7 +1612,7 @@ class stable_vector
template <class FwdIterator>
void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
{
multiallocation_chain mem(get_al().allocate_individual(n));
multiallocation_chain mem(node_alloc().allocate_individual(n));
size_type i = 0;
node_type_ptr_t p = 0;
@@ -1525,7 +1621,7 @@ class stable_vector
p = mem.front();
mem.pop_front();
//This can throw
boost::container::construct_in_place(&*p, first);
boost::container::construct_in_place(this->node_alloc(), &*p, first);
p->set_pointer(void_ptr_ptr(&it[i]));
++first;
it[i] = p;
@@ -1533,8 +1629,8 @@ class stable_vector
}
}
catch(...){
get_al().deallocate_one(p);
get_al().deallocate_many(boost::move(mem));
node_alloc().deallocate_one(p);
node_alloc().deallocate_many(boost::move(mem));
impl_iterator e = impl.erase(it+i, it+n);
this->align_nodes(e, get_last_align());
throw;
@@ -1548,13 +1644,13 @@ class stable_vector
node_type_ptr_t p = 0;
try{
while(first != last){
p = get_from_pool();
p = this->get_from_pool();
if(!p){
insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
break;
}
//This can throw
boost::container::construct_in_place(&*p, first);
boost::container::construct_in_place(this->node_alloc(), &*p, first);
p->set_pointer(void_ptr_ptr(&it[i]));
++first;
it[i]=p;
@@ -1575,16 +1671,6 @@ class stable_vector
this->insert_not_iter(position, first, last);
}
static void swap_impl(stable_vector& x,stable_vector& y)
{
using std::swap;
swap(x.get_al(),y.get_al());
swap(x.impl,y.impl);
swap(x.internal_data.pool_size, y.internal_data.pool_size);
x.readjust_end_node();
y.readjust_end_node();
}
#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
bool invariant()const
{
@@ -1609,9 +1695,12 @@ class stable_vector
return n >= num_pool;
}
class invariant_checker:private boost::noncopyable
class invariant_checker
{
invariant_checker(const invariant_checker &);
invariant_checker & operator=(const invariant_checker &);
const stable_vector* p;
public:
invariant_checker(const stable_vector& v):p(&v){}
~invariant_checker(){BOOST_ASSERT(p->invariant());}
@@ -1619,11 +1708,32 @@ class stable_vector
};
#endif
struct ebo_holder
: node_allocator_type
class ebo_holder
: public node_allocator_type
{
ebo_holder(const allocator_type &a)
: node_allocator_type(a), pool_size(0), end_node()
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
public:
/*
explicit ebo_holder(BOOST_RV_REF(ebo_holder) x)
: node_allocator_type(boost::move(static_cast<node_allocator_type&>(x)))
, pool_size(0)
, end_node()
{}
*/
template<class AllocatorRLValue>
explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
: node_allocator_type(boost::forward<AllocatorRLValue>(a))
, pool_size(0)
, end_node()
{
this->set_end_pointer_to_default_constructed();
}
ebo_holder()
: node_allocator_type()
, pool_size(0)
, end_node()
{
this->set_end_pointer_to_default_constructed();
}
@@ -1637,8 +1747,15 @@ class stable_vector
node_type_base_t end_node;
} internal_data;
node_allocator_type &get_al() { return internal_data; }
const node_allocator_type &get_al() const { return internal_data; }
void priv_swap_members(stable_vector &x)
{
container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
this->readjust_end_node();
x.readjust_end_node();
}
node_allocator_type &node_alloc() { return internal_data; }
const node_allocator_type &node_alloc() const { return internal_data; }
impl_type impl;
/// @endcond

View File

@@ -30,8 +30,8 @@
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied warranty.
#ifndef BOOST_CONTAINERS_STRING_HPP
#define BOOST_CONTAINERS_STRING_HPP
#ifndef BOOST_CONTAINER_STRING_HPP
#define BOOST_CONTAINER_STRING_HPP
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
@@ -43,6 +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/detail/mpl.hpp>
#include <boost/move/move.hpp>
#include <boost/static_assert.hpp>
@@ -75,7 +76,7 @@ namespace container {
#endif
/// @cond
namespace containers_detail {
namespace container_detail {
// ------------------------------------------------------------
// Class basic_string_base.
@@ -89,16 +90,20 @@ namespace containers_detail {
template <class A>
class basic_string_base
{
basic_string_base();
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base)
typedef allocator_traits<A> allocator_traits_type;
public:
typedef A allocator_type;
//! The stored allocator type
typedef allocator_type stored_allocator_type;
typedef typename A::pointer pointer;
typedef typename A::value_type value_type;
typedef typename A::size_type size_type;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::value_type value_type;
typedef typename allocator_traits_type::size_type size_type;
basic_string_base()
: members_()
{ init(); }
basic_string_base(const allocator_type& a)
: members_(a)
@@ -112,16 +117,16 @@ class basic_string_base
}
basic_string_base(BOOST_RV_REF(basic_string_base) b)
: members_(b.members_)
: members_(boost::move(b.alloc()))
{
init();
this->swap(b);
this->init();
this->swap_data(b);
}
~basic_string_base()
{
this->deallocate_block();
if(!this->is_short()){
this->deallocate_block();
static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
}
}
@@ -169,14 +174,14 @@ class basic_string_base
//so, unlike long_t, it can be placed in a union
typedef typename boost::aligned_storage< sizeof(long_t),
containers_detail::alignment_of<long_t>::value>::type long_raw_t;
container_detail::alignment_of<long_t>::value>::type long_raw_t;
protected:
static const size_type MinInternalBufferChars = 8;
static const size_type AlignmentOfValueType =
alignment_of<value_type>::value;
static const size_type ShortDataOffset =
containers_detail::ct_rounded_size<sizeof(short_header), AlignmentOfValueType>::value;
container_detail::ct_rounded_size<sizeof(short_header), AlignmentOfValueType>::value;
static const size_type ZeroCostInternalBufferChars =
(sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
static const size_type UnalignedFinalInternalBufferChars =
@@ -204,8 +209,13 @@ class basic_string_base
struct members_holder
: public A
{
members_holder(const A &a)
: A(a)
members_holder()
: A()
{}
template<class AllocatorConvertible>
explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a)
: A(boost::forward<AllocatorConvertible>(a))
{}
repr_t m_repr;
@@ -247,10 +257,10 @@ class basic_string_base
protected:
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
typedef containers_detail::integral_constant<unsigned,
boost::container::containers_detail::version<A>::value> alloc_version;
typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::version<A>::value> alloc_version;
std::pair<pointer, bool>
allocation_command(allocation_type command,
@@ -295,7 +305,7 @@ class basic_string_base
}
size_type next_capacity(size_type additional_objects) const
{ return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects); }
{ return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects); }
void deallocate(pointer p, size_type n)
{
@@ -304,16 +314,16 @@ class basic_string_base
}
void construct(pointer p, const value_type &value = value_type())
{ new((void*)containers_detail::get_pointer(p)) value_type(value); }
{ new((void*)container_detail::to_raw_pointer(p)) value_type(value); }
void destroy(pointer p, size_type n)
{
for(; n--; ++p)
containers_detail::get_pointer(p)->~value_type();
container_detail::to_raw_pointer(p)->~value_type();
}
void destroy(pointer p)
{ containers_detail::get_pointer(p)->~value_type(); }
{ container_detail::to_raw_pointer(p)->~value_type(); }
void allocate_initial_block(size_type n)
{
@@ -335,7 +345,7 @@ class basic_string_base
{ this->deallocate(this->priv_addr(), this->priv_storage()); }
size_type max_size() const
{ return this->alloc().max_size() - 1; }
{ return allocator_traits_type::max_size(this->alloc()) - 1; }
// Helper functions for exception handling.
void throw_length_error() const
@@ -404,14 +414,14 @@ class basic_string_base
void priv_long_size(size_type sz)
{
this->members_.m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
this->members_.m_repr.long_repr().length = static_cast<typename allocator_traits_type::size_type>(sz);
}
void swap(basic_string_base& other)
void swap_data(basic_string_base& other)
{
if(this->is_short()){
if(other.is_short()){
std::swap(this->members_.m_repr, other.members_.m_repr);
container_detail::do_swap(this->members_.m_repr, other.members_.m_repr);
}
else{
repr_t copied(this->members_.m_repr);
@@ -426,18 +436,13 @@ class basic_string_base
this->members_.m_repr = copied;
}
else{
std::swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
container_detail::do_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
}
}
allocator_type & this_al = this->alloc(), &other_al = other.alloc();
if(this_al != other_al){
containers_detail::do_swap(this_al, other_al);
}
}
};
} //namespace containers_detail {
} //namespace container_detail {
/// @endcond
@@ -475,12 +480,13 @@ template <class CharT, class Traits = std::char_traits<CharT>, class A = std::al
template <class CharT, class Traits, class A>
#endif
class basic_string
: private containers_detail::basic_string_base<A>
: private container_detail::basic_string_base<A>
{
/// @cond
private:
typedef allocator_traits<A> allocator_traits_type;
BOOST_COPYABLE_AND_MOVABLE(basic_string)
typedef containers_detail::basic_string_base<A> base_t;
typedef container_detail::basic_string_base<A> base_t;
static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
protected:
@@ -527,17 +533,17 @@ class basic_string
//! The second template parameter Traits
typedef Traits traits_type;
//! Pointer to CharT
typedef typename A::pointer pointer;
typedef typename allocator_traits_type::pointer pointer;
//! Const pointer to CharT
typedef typename A::const_pointer const_pointer;
typedef typename allocator_traits_type::const_pointer const_pointer;
//! Reference to CharT
typedef typename A::reference reference;
typedef typename allocator_traits_type::reference reference;
//! Const reference to CharT
typedef typename A::const_reference const_reference;
typedef typename allocator_traits_type::const_reference const_reference;
//! An unsigned integral type
typedef typename A::size_type size_type;
typedef typename allocator_traits_type::size_type size_type;
//! A signed integral type
typedef typename A::difference_type difference_type;
typedef typename allocator_traits_type::difference_type difference_type;
//! Iterator used to iterate through a string. It's a Random Access Iterator
typedef pointer iterator;
//! Const iterator used to iterate through a string. It's a Random Access Iterator
@@ -562,17 +568,28 @@ class basic_string
struct reserve_t {};
basic_string(reserve_t, size_type n,
const allocator_type& a = allocator_type())
: base_t(a, n + 1)
const allocator_type& a = allocator_type())
//Select allocator as in copy constructor as reserve_t-based constructors
//are two step copies optimized for capacity
: base_t( allocator_traits_type::select_on_container_copy_construction(a)
, n + 1)
{ this->priv_terminate_string(); }
/// @endcond
//! <b>Effects</b>: Default constructs a basic_string.
//!
//! <b>Throws</b>: If allocator_type's default constructor throws.
basic_string()
: base_t()
{ this->priv_terminate_string(); }
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
explicit basic_string(const allocator_type& a = allocator_type())
: base_t(a, InternalBufferChars)
explicit basic_string(const allocator_type& a)
: base_t(a)
{ this->priv_terminate_string(); }
//! <b>Effects</b>: Copy constructs a basic_string.
@@ -581,7 +598,7 @@ class basic_string
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
basic_string(const basic_string& s)
: base_t(s.alloc())
: 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.
@@ -603,7 +620,7 @@ class basic_string
this->throw_out_of_range();
else
this->priv_range_initialize
(s.begin() + pos, s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
(s.begin() + pos, s.begin() + pos + container_detail::min_value(n, s.size() - pos));
}
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
@@ -638,8 +655,8 @@ class basic_string
: base_t(a)
{
//Dispatch depending on integer/iterator
const bool aux_boolean = containers_detail::is_convertible<InputIterator, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InputIterator, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
this->priv_initialize_dispatch(f, l, Result());
}
@@ -656,10 +673,24 @@ class basic_string
//! <b>Postcondition</b>: x == *this.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) s)
basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) x)
{
if (&s != this)
this->assign(s.begin(), s.end());
if (&x != this){
allocator_type &this_alloc = this->alloc();
const allocator_type &x_alloc = x.alloc();
container_detail::bool_<allocator_traits_type::
propagate_on_container_copy_assignment::value> flag;
if(flag && this_alloc != x_alloc){
if(!this->is_short()){
this->deallocate_block();
this->is_short(true);
Traits::assign(*this->priv_addr(), this->priv_null());
this->priv_size(0);
}
}
container_detail::assign_alloc(this->alloc(), x.alloc(), flag);
this->assign(x.begin(), x.end());
}
return *this;
}
@@ -668,11 +699,25 @@ class basic_string
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
basic_string& operator=(BOOST_RV_REF(basic_string) ms)
basic_string& operator=(BOOST_RV_REF(basic_string) x)
{
basic_string &s = ms;
if (&s != this){
this->swap(s);
if (&x != this){
allocator_type &this_alloc = this->alloc();
allocator_type &x_alloc = x.alloc();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy objects but retain memory in case x reuses it in the future
this->clear();
this->swap_data(x);
//Move allocator if needed
container_detail::bool_<allocator_traits_type::
propagate_on_container_move_assignment::value> flag;
container_detail::move_alloc(this_alloc, x_alloc, flag);
}
//If unequal allocators, then do a one by one move
else{
this->assign( x.begin(), x.end());
}
}
return *this;
}
@@ -709,7 +754,6 @@ class basic_string
const_iterator cbegin() const
{ return this->priv_addr(); }
//! <b>Effects</b>: Returns an iterator to the end of the vector.
//!
//! <b>Throws</b>: Nothing.
@@ -796,6 +840,26 @@ class basic_string
allocator_type get_allocator() const
{ return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
//!
//! <b>Throws</b>: Nothing.
@@ -855,7 +919,7 @@ class basic_string
this->throw_length_error();
if (this->capacity() < res_arg){
size_type n = containers_detail::max_value(res_arg, this->size()) + 1;
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
size_type new_cap = this->next_capacity(n);
pointer new_start = this->allocation_command
(allocate_new, n, new_cap, new_cap).first;
@@ -912,8 +976,8 @@ class basic_string
size_type long_storage = this->priv_long_storage();
size_type long_size = this->priv_long_size();
//Shrink from allocated buffer to the internal one, including trailing null
Traits::copy( containers_detail::get_pointer(this->priv_short_addr())
, containers_detail::get_pointer(long_addr)
Traits::copy( container_detail::to_raw_pointer(this->priv_short_addr())
, container_detail::to_raw_pointer(long_addr)
, long_size+1);
this->is_short(true);
this->alloc().deallocate(long_addr, long_storage);
@@ -1020,7 +1084,7 @@ class basic_string
if (pos > s.size())
this->throw_out_of_range();
return this->append(s.begin() + pos,
s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
s.begin() + pos + container_detail::min_value(n, s.size() - pos));
}
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
@@ -1087,7 +1151,7 @@ class basic_string
//!
//! <b>Returns</b>: *this
basic_string& assign(BOOST_RV_REF(basic_string) ms)
{ return this->swap(ms), *this; }
{ return this->swap_data(ms), *this; }
//! <b>Requires</b>: pos <= str.size()
//!
@@ -1102,7 +1166,7 @@ class basic_string
if (pos > s.size())
this->throw_out_of_range();
return this->assign(s.begin() + pos,
s.begin() + pos + containers_detail::min_value(n, s.size() - pos));
s.begin() + pos + container_detail::min_value(n, s.size() - pos));
}
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
@@ -1137,8 +1201,8 @@ class basic_string
basic_string& assign(InputIter first, InputIter last)
{
//Dispatch depending on integer/iterator
const bool aux_boolean = containers_detail::is_convertible<InputIter, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InputIter, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
return this->priv_assign_dispatch(first, last, Result());
}
@@ -1172,10 +1236,10 @@ class basic_string
{
if (pos1 > this->size() || pos2 > s.size())
this->throw_out_of_range();
size_type len = containers_detail::min_value(n, s.size() - pos2);
size_type len = container_detail::min_value(n, s.size() - pos2);
if (this->size() > this->max_size() - len)
this->throw_length_error();
const CharT *beg_ptr = containers_detail::get_pointer(s.begin()) + pos2;
const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2;
const CharT *end_ptr = beg_ptr + len;
this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
return *this;
@@ -1271,8 +1335,8 @@ class basic_string
void insert(const_iterator p, InputIter first, InputIter last)
{
//Dispatch depending on integer/iterator
const bool aux_boolean = containers_detail::is_convertible<InputIter, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InputIter, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
this->priv_insert_dispatch(p, first, last, Result());
}
@@ -1291,7 +1355,7 @@ class basic_string
{
if (pos > size())
this->throw_out_of_range();
erase(this->priv_addr() + pos, this->priv_addr() + pos + containers_detail::min_value(n, size() - pos));
erase(this->priv_addr() + pos, this->priv_addr() + pos + container_detail::min_value(n, size() - pos));
return *this;
}
@@ -1304,9 +1368,9 @@ class basic_string
iterator erase(const_iterator p)
{
// The move includes the terminating null.
CharT *ptr = const_cast<CharT*>(containers_detail::get_pointer(p));
CharT *ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
Traits::move(ptr,
containers_detail::get_pointer(p + 1),
container_detail::to_raw_pointer(p + 1),
this->priv_size() - (p - this->priv_addr()));
this->priv_size(this->priv_size()-1);
return iterator(ptr);
@@ -1322,11 +1386,11 @@ class basic_string
//! the other elements being erased. If no such element exists, end() is returned.
iterator erase(const_iterator first, const_iterator last)
{
CharT * f = const_cast<CharT*>(containers_detail::get_pointer(first));
CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
if (first != last) { // The move includes the terminating null.
size_type num_erased = last - first;
Traits::move(f,
containers_detail::get_pointer(last),
container_detail::to_raw_pointer(last),
(this->priv_size() + 1)-(last - this->priv_addr()));
size_type new_length = this->priv_size() - num_erased;
this->priv_size(new_length);
@@ -1356,7 +1420,7 @@ class basic_string
{
if (pos1 > size())
this->throw_out_of_range();
const size_type len = containers_detail::min_value(n1, size() - pos1);
const size_type len = container_detail::min_value(n1, size() - pos1);
if (this->size() - len >= this->max_size() - str.size())
this->throw_length_error();
return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
@@ -1377,8 +1441,8 @@ class basic_string
{
if (pos1 > size() || pos2 > str.size())
this->throw_out_of_range();
const size_type len1 = containers_detail::min_value(n1, size() - pos1);
const size_type len2 = containers_detail::min_value(n2, str.size() - pos2);
const size_type len1 = container_detail::min_value(n1, size() - pos1);
const size_type len2 = container_detail::min_value(n2, str.size() - pos2);
if (this->size() - len1 >= this->max_size() - len2)
this->throw_length_error();
return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len1,
@@ -1404,7 +1468,7 @@ class basic_string
{
if (pos1 > size())
this->throw_out_of_range();
const size_type len = containers_detail::min_value(n1, size() - pos1);
const size_type len = container_detail::min_value(n1, size() - pos1);
if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
this->throw_length_error();
return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
@@ -1429,7 +1493,7 @@ class basic_string
{
if (pos > size())
this->throw_out_of_range();
const size_type len = containers_detail::min_value(n1, size() - pos);
const size_type len = container_detail::min_value(n1, size() - pos);
const size_type n2 = Traits::length(s);
if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
this->throw_length_error();
@@ -1449,7 +1513,7 @@ class basic_string
{
if (pos1 > size())
this->throw_out_of_range();
const size_type len = containers_detail::min_value(n1, size() - pos1);
const size_type len = container_detail::min_value(n1, size() - pos1);
if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
this->throw_length_error();
return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len, n2, c);
@@ -1498,11 +1562,11 @@ class basic_string
{
const size_type len = static_cast<size_type>(i2 - i1);
if (len >= n) {
Traits::assign(const_cast<CharT*>(containers_detail::get_pointer(i1)), n, c);
Traits::assign(const_cast<CharT*>(container_detail::to_raw_pointer(i1)), n, c);
erase(i1 + n, i2);
}
else {
Traits::assign(const_cast<CharT*>(containers_detail::get_pointer(i1)), len, c);
Traits::assign(const_cast<CharT*>(container_detail::to_raw_pointer(i1)), len, c);
insert(i2, n - len, c);
}
return *this;
@@ -1519,8 +1583,8 @@ class basic_string
basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2)
{
//Dispatch depending on integer/iterator
const bool aux_boolean = containers_detail::is_convertible<InputIter, size_type>::value;
typedef containers_detail::bool_<aux_boolean> Result;
const bool aux_boolean = container_detail::is_convertible<InputIter, size_type>::value;
typedef container_detail::bool_<aux_boolean> Result;
return this->priv_replace_dispatch(i1, i2, j1, j2, Result());
}
@@ -1539,8 +1603,8 @@ class basic_string
{
if (pos > size())
this->throw_out_of_range();
const size_type len = containers_detail::min_value(n, size() - pos);
Traits::copy(s, containers_detail::get_pointer(this->priv_addr() + pos), len);
const size_type len = container_detail::min_value(n, size() - pos);
Traits::copy(s, container_detail::to_raw_pointer(this->priv_addr() + pos), len);
return len;
}
@@ -1549,7 +1613,11 @@ class basic_string
//!
//! <b>Throws</b>: Nothing
void swap(basic_string& x)
{ base_t::swap(x); }
{
this->base_t::swap_data(x);
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
}
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//!
@@ -1557,7 +1625,7 @@ class basic_string
//!
//! <b>Complexity</b>: constant time.
const CharT* c_str() const
{ return containers_detail::get_pointer(this->priv_addr()); }
{ return container_detail::to_raw_pointer(this->priv_addr()); }
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//!
@@ -1565,7 +1633,7 @@ class basic_string
//!
//! <b>Complexity</b>: constant time.
const CharT* data() const
{ return containers_detail::get_pointer(this->priv_addr()); }
{ return container_detail::to_raw_pointer(this->priv_addr()); }
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
//! of the following conditions obtain: 19 pos <= xpos and xpos + str.size() <= size();
@@ -1589,8 +1657,8 @@ class basic_string
else {
pointer finish = this->priv_addr() + this->priv_size();
const const_iterator result =
std::search(containers_detail::get_pointer(this->priv_addr() + pos),
containers_detail::get_pointer(finish),
std::search(container_detail::to_raw_pointer(this->priv_addr() + pos),
container_detail::to_raw_pointer(finish),
s, s + n, Eq_traits<Traits>());
return result != finish ? result - begin() : npos;
}
@@ -1643,9 +1711,9 @@ class basic_string
if (n > len)
return npos;
else if (n == 0)
return containers_detail::min_value(len, pos);
return container_detail::min_value(len, pos);
else {
const const_iterator last = begin() + containers_detail::min_value(len - n, pos) + n;
const const_iterator last = begin() + container_detail::min_value(len - n, pos) + n;
const const_iterator result = find_end(begin(), last,
s, s + n,
Eq_traits<Traits>());
@@ -1672,7 +1740,7 @@ class basic_string
if (len < 1)
return npos;
else {
const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
const_reverse_iterator rresult =
std::find_if(const_reverse_iterator(last), rend(),
std::bind2nd(Eq_traits<Traits>(), c));
@@ -1746,7 +1814,7 @@ class basic_string
if (len < 1)
return npos;
else {
const const_iterator last = this->priv_addr() + containers_detail::min_value(len - 1, pos) + 1;
const const_iterator last = this->priv_addr() + container_detail::min_value(len - 1, pos) + 1;
const const_reverse_iterator rresult =
std::find_first_of(const_reverse_iterator(last), rend(),
s, s + n,
@@ -1843,7 +1911,7 @@ class basic_string
if (len < 1)
return npos;
else {
const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
const const_reverse_iterator rresult =
std::find_if(const_reverse_iterator(last), rend(),
Not_within_traits<Traits>(s, s + n));
@@ -1869,7 +1937,7 @@ class basic_string
if (len < 1)
return npos;
else {
const const_iterator last = begin() + containers_detail::min_value(len - 1, pos) + 1;
const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
const_reverse_iterator rresult =
std::find_if(const_reverse_iterator(last), rend(),
std::not1(std::bind2nd(Eq_traits<Traits>(), c)));
@@ -1890,7 +1958,7 @@ class basic_string
if (pos > size())
this->throw_out_of_range();
return basic_string(this->priv_addr() + pos,
this->priv_addr() + pos + containers_detail::min_value(n, size() - pos), this->alloc());
this->priv_addr() + pos + container_detail::min_value(n, size() - pos), this->alloc());
}
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as
@@ -1918,7 +1986,7 @@ class basic_string
if (pos1 > size())
this->throw_out_of_range();
return s_compare(this->priv_addr() + pos1,
this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
this->priv_addr() + pos1 + container_detail::min_value(n1, size() - pos1),
str.priv_addr(), str.priv_addr() + str.priv_size());
}
@@ -1935,9 +2003,9 @@ class basic_string
if (pos1 > size() || pos2 > str.size())
this->throw_out_of_range();
return s_compare(this->priv_addr() + pos1,
this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
this->priv_addr() + pos1 + container_detail::min_value(n1, size() - pos1),
str.priv_addr() + pos2,
str.priv_addr() + pos2 + containers_detail::min_value(n2, size() - pos2));
str.priv_addr() + pos2 + container_detail::min_value(n2, size() - pos2));
}
//! <b>Throws</b>: Nothing
@@ -1958,7 +2026,7 @@ class basic_string
if (pos1 > size())
this->throw_out_of_range();
return s_compare(this->priv_addr() + pos1,
this->priv_addr() + pos1 + containers_detail::min_value(n1, size() - pos1),
this->priv_addr() + pos1 + container_detail::min_value(n1, size() - pos1),
s, s + n2);
}
@@ -1977,13 +2045,16 @@ class basic_string
{
const difference_type n1 = l1 - f1;
const difference_type n2 = l2 - f2;
const int cmp = Traits::compare(containers_detail::get_pointer(f1),
containers_detail::get_pointer(f2),
containers_detail::min_value(n1, n2));
const int cmp = Traits::compare(container_detail::to_raw_pointer(f1),
container_detail::to_raw_pointer(f2),
container_detail::min_value(n1, n2));
return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
}
void priv_shrink_to_fit_dynamic_buffer(allocator_v1)
template<class AllocVersion>
void priv_shrink_to_fit_dynamic_buffer
( AllocVersion
, typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v1> >::type* = 0)
{
//Allocate a new buffer.
size_type real_cap = 0;
@@ -1995,8 +2066,8 @@ class basic_string
std::pair<pointer, bool> ret = this->allocation_command
(allocate_new, long_size+1, long_size+1, real_cap, long_addr);
//Copy and update
Traits::copy( containers_detail::get_pointer(ret.first)
, containers_detail::get_pointer(this->priv_long_addr())
Traits::copy( container_detail::to_raw_pointer(ret.first)
, container_detail::to_raw_pointer(this->priv_long_addr())
, long_size+1);
this->priv_long_addr(ret.first);
this->priv_storage(real_cap);
@@ -2008,7 +2079,10 @@ class basic_string
}
}
void priv_shrink_to_fit_dynamic_buffer(allocator_v2)
template<class AllocVersion>
void priv_shrink_to_fit_dynamic_buffer
( AllocVersion
, typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v2> >::type* = 0)
{
size_type received_size;
if(this->alloc().allocation_command
@@ -2044,7 +2118,7 @@ class basic_string
std::forward_iterator_tag)
{
difference_type n = std::distance(f, l);
this->allocate_initial_block(containers_detail::max_value<difference_type>(n+1, InternalBufferChars));
this->allocate_initial_block(container_detail::max_value<difference_type>(n+1, InternalBufferChars));
priv_uninitialized_copy(f, l, this->priv_addr());
this->priv_size(n);
this->priv_terminate_string();
@@ -2058,16 +2132,16 @@ class basic_string
}
template <class Integer>
void priv_initialize_dispatch(Integer n, Integer x, containers_detail::true_)
void priv_initialize_dispatch(Integer n, Integer x, container_detail::true_)
{
this->allocate_initial_block(containers_detail::max_value<difference_type>(n+1, InternalBufferChars));
this->allocate_initial_block(container_detail::max_value<difference_type>(n+1, InternalBufferChars));
priv_uninitialized_fill_n(this->priv_addr(), n, x);
this->priv_size(n);
this->priv_terminate_string();
}
template <class InputIter>
void priv_initialize_dispatch(InputIter f, InputIter l, containers_detail::false_)
void priv_initialize_dispatch(InputIter f, InputIter l, container_detail::false_)
{ this->priv_range_initialize(f, l); }
template<class FwdIt, class Count> inline
@@ -2117,15 +2191,15 @@ class basic_string
}
template <class Integer>
basic_string& priv_assign_dispatch(Integer n, Integer x, containers_detail::true_)
basic_string& priv_assign_dispatch(Integer n, Integer x, container_detail::true_)
{ return this->assign((size_type) n, (CharT) x); }
template <class InputIter>
basic_string& priv_assign_dispatch(InputIter f, InputIter l,
containers_detail::false_)
container_detail::false_)
{
size_type cur = 0;
CharT *ptr = containers_detail::get_pointer(this->priv_addr());
CharT *ptr = container_detail::to_raw_pointer(this->priv_addr());
while (f != l && cur != this->priv_size()) {
Traits::assign(*ptr, *f);
++f;
@@ -2189,10 +2263,10 @@ class basic_string
pointer_past_last, pointer_past_last);
this->priv_size(this->priv_size()+n);
Traits::move(const_cast<CharT*>(containers_detail::get_pointer(position + n)),
containers_detail::get_pointer(position),
Traits::move(const_cast<CharT*>(container_detail::to_raw_pointer(position + n)),
container_detail::to_raw_pointer(position),
(elems_after - n) + 1);
this->priv_copy(first, last, const_cast<CharT*>(containers_detail::get_pointer(position)));
this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(position)));
}
else {
ForwardIter mid = first;
@@ -2204,7 +2278,7 @@ class basic_string
(position, const_iterator(this->priv_addr() + old_length + 1),
this->priv_addr() + this->priv_size());
this->priv_size(this->priv_size() + elems_after);
this->priv_copy(first, mid, const_cast<CharT*>(containers_detail::get_pointer(position)));
this->priv_copy(first, mid, const_cast<CharT*>(container_detail::to_raw_pointer(position)));
}
}
else{
@@ -2231,9 +2305,9 @@ class basic_string
else{
//value_type is POD, so backwards expansion is much easier
//than with vector<T>
value_type *oldbuf = containers_detail::get_pointer(old_start);
value_type *newbuf = containers_detail::get_pointer(new_start);
const value_type *pos = containers_detail::get_pointer(position);
value_type *oldbuf = container_detail::to_raw_pointer(old_start);
value_type *newbuf = container_detail::to_raw_pointer(new_start);
const value_type *pos = container_detail::to_raw_pointer(position);
size_type before = pos - oldbuf;
//First move old data
@@ -2253,12 +2327,12 @@ class basic_string
template <class Integer>
void priv_insert_dispatch(const_iterator p, Integer n, Integer x,
containers_detail::true_)
container_detail::true_)
{ insert(p, (size_type) n, (CharT) x); }
template <class InputIter>
void priv_insert_dispatch(const_iterator p, InputIter first, InputIter last,
containers_detail::false_)
container_detail::false_)
{
typedef typename std::iterator_traits<InputIter>::iterator_category Category;
priv_insert(p, first, last, Category());
@@ -2277,13 +2351,13 @@ class basic_string
template <class Integer>
basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
Integer n, Integer x,
containers_detail::true_)
container_detail::true_)
{ return this->replace(first, last, (size_type) n, (CharT) x); }
template <class InputIter>
basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
InputIter f, InputIter l,
containers_detail::false_)
container_detail::false_)
{
typedef typename std::iterator_traits<InputIter>::iterator_category Category;
return this->priv_replace(first, last, f, l, Category());
@@ -2312,13 +2386,13 @@ class basic_string
difference_type n = std::distance(f, l);
const difference_type len = last - first;
if (len >= n) {
this->priv_copy(f, l, const_cast<CharT*>(containers_detail::get_pointer(first)));
this->priv_copy(f, l, const_cast<CharT*>(container_detail::to_raw_pointer(first)));
this->erase(first + n, last);
}
else {
ForwardIter m = f;
std::advance(m, len);
this->priv_copy(f, m, const_cast<CharT*>(containers_detail::get_pointer(first)));
this->priv_copy(f, m, const_cast<CharT*>(container_detail::to_raw_pointer(first)));
this->insert(last, m, l);
}
return *this;
@@ -2364,10 +2438,20 @@ operator+(const basic_string<CharT,Traits,A>& x,
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
str_t result(reserve, x.size() + y.size(), x.alloc());
str_t result(reserve, x.size() + y.size(), x.get_stored_allocator());
result.append(x);
result.append(y);
return result;
return boost::move(result);
}
template <class CharT, class Traits, class A> inline
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
operator+(
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
, BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{
mx += my;
return boost::move(mx);
}
template <class CharT, class Traits, class A> inline
@@ -2386,7 +2470,8 @@ BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
return my.replace(size_type(0), size_type(0), x);
my.replace(size_type(0), size_type(0), x);
return boost::move(my);
}
template <class CharT, class Traits, class A>
@@ -2400,7 +2485,7 @@ operator+(const CharT* s, const basic_string<CharT,Traits,A>& y)
str_t result(reserve, n + y.size());
result.append(s, s + n);
result.append(y);
return result;
return boost::move(result);
}
template <class CharT, class Traits, class A> inline
@@ -2409,7 +2494,7 @@ operator+(const CharT* s,
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
return boost::move(my.get().replace(size_type(0), size_type(0), s));
return boost::move(my.replace(size_type(0), size_type(0), s));
}
template <class CharT, class Traits, class A>
@@ -2422,7 +2507,7 @@ operator+(CharT c, const basic_string<CharT,Traits,A>& y)
str_t result(reserve, 1 + y.size());
result.push_back(c);
result.append(y);
return result;
return boost::move(result);
}
template <class CharT, class Traits, class A> inline
@@ -2431,7 +2516,7 @@ operator+(CharT c,
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{
typedef typename basic_string<CharT,Traits,A>::size_type size_type;
return my.replace(size_type(0), size_type(0), &c, &c + 1);
return boost::move(my.replace(size_type(0), size_type(0), &c, &c + 1));
}
template <class CharT, class Traits, class A>
@@ -2442,10 +2527,10 @@ operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
const typename str_t::size_type n = Traits::length(s);
str_t result(reserve, x.size() + n, x.alloc());
str_t result(reserve, x.size() + n, x.get_stored_allocator());
result.append(x);
result.append(s, s + n);
return result;
return boost::move(result);
}
template <class CharT, class Traits, class A>
@@ -2461,13 +2546,13 @@ template <class CharT, class Traits, class A>
inline basic_string<CharT,Traits,A>
operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
{
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
str_t result(reserve, x.size() + 1, x.alloc());
str_t result(reserve, x.size() + 1, x.get_stored_allocator());
result.append(x);
result.push_back(c);
return result;
return boost::move(result);
}
template <class CharT, class Traits, class A>
@@ -2616,7 +2701,7 @@ inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>&
/// @cond
// I/O.
namespace containers_detail {
namespace container_detail {
template <class CharT, class Traits>
inline bool
@@ -2633,7 +2718,7 @@ string_fill(std::basic_ostream<CharT, Traits>& os,
return ok;
}
} //namespace containers_detail {
} //namespace container_detail {
/// @endcond
template <class CharT, class Traits, class A>
@@ -2655,13 +2740,13 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Trait
pad_len = w - n;
if (!left)
ok = containers_detail::string_fill(os, buf, pad_len);
ok = container_detail::string_fill(os, buf, pad_len);
ok = ok &&
buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
if (left)
ok = ok && containers_detail::string_fill(os, buf, pad_len);
ok = ok && container_detail::string_fill(os, buf, pad_len);
}
if (!ok)
@@ -2783,4 +2868,4 @@ struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, A>
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINERS_STRING_HPP
#endif // BOOST_CONTAINER_STRING_HPP

File diff suppressed because it is too large Load Diff