mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Introducing allocator_traits and pointer_traits changes into several libraries.
[SVN r76106]
This commit is contained in:
381
include/boost/container/allocator/allocator_traits.hpp
Normal file
381
include/boost/container/allocator/allocator_traits.hpp
Normal 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)
|
77
include/boost/container/allocator/memory_util.hpp
Normal file
77
include/boost/container/allocator/memory_util.hpp
Normal 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)
|
651
include/boost/container/allocator/scoped_allocator.hpp
Normal file
651
include/boost/container/allocator/scoped_allocator.hpp
Normal 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
|
@@ -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
@@ -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 {
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
88
include/boost/container/detail/function_detector.hpp
Normal file
88
include/boost/container/detail/function_detector.hpp
Normal 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
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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_
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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_
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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
|
||||
|
@@ -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
Reference in New Issue
Block a user