Initial Commit
This commit is contained in:
@@ -0,0 +1,477 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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-2013. 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
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// container
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp> //is_empty
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
#endif
|
||||
// intrusive
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
// move
|
||||
#include <boost/move/utility_core.hpp>
|
||||
// move/detail
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
// other boost
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template<class Allocator>
|
||||
class small_vector_allocator;
|
||||
|
||||
namespace allocator_traits_detail {
|
||||
|
||||
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size)
|
||||
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction)
|
||||
|
||||
} //namespace allocator_traits_detail {
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
//workaround needed for C++03 compilers with no construct()
|
||||
//supporting rvalue references
|
||||
template<class Allocator>
|
||||
struct is_std_allocator
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<class T>
|
||||
struct is_std_allocator< std::allocator<T> >
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<class T>
|
||||
struct is_std_allocator< small_vector_allocator< std::allocator<T> > >
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<class Allocator>
|
||||
struct is_not_std_allocator
|
||||
{ static const bool value = !is_std_allocator<Allocator>::value; };
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_EVAL_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(is_always_equal)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable)
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The class template allocator_traits supplies a uniform interface to all allocator types.
|
||||
//! This class is a C++03-compatible implementation of std::allocator_traits
|
||||
template <typename Allocator>
|
||||
struct allocator_traits
|
||||
{
|
||||
//allocator_type
|
||||
typedef Allocator allocator_type;
|
||||
//value_type
|
||||
typedef typename allocator_type::value_type value_type;
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! Allocator::pointer if such a type exists; otherwise, value_type*
|
||||
//!
|
||||
typedef unspecified pointer;
|
||||
//! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
|
||||
//!
|
||||
typedef see_documentation const_pointer;
|
||||
//! Non-standard extension
|
||||
//! Allocator::reference if such a type exists; otherwise, value_type&
|
||||
typedef see_documentation reference;
|
||||
//! Non-standard extension
|
||||
//! Allocator::const_reference if such a type exists ; otherwise, const value_type&
|
||||
typedef see_documentation const_reference;
|
||||
//! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
|
||||
//!
|
||||
typedef see_documentation void_pointer;
|
||||
//! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
|
||||
//!
|
||||
typedef see_documentation const_void_pointer;
|
||||
//! Allocator::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
|
||||
//!
|
||||
typedef see_documentation difference_type;
|
||||
//! Allocator::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
|
||||
//!
|
||||
typedef see_documentation size_type;
|
||||
//! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type
|
||||
//! with an internal constant static boolean member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_copy_assignment;
|
||||
//! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type
|
||||
//! with an internal constant static boolean member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_move_assignment;
|
||||
//! Allocator::propagate_on_container_swap if such a type exists, otherwise a type
|
||||
//! with an internal constant static boolean member <code>value</code> == false.
|
||||
typedef see_documentation propagate_on_container_swap;
|
||||
//! Allocator::is_always_equal if such a type exists, otherwise a type
|
||||
//! with an internal constant static boolean member <code>value</code> == is_empty<Allocator>::value
|
||||
typedef see_documentation is_always_equal;
|
||||
//! Allocator::is_partially_propagable if such a type exists, otherwise a type
|
||||
//! with an internal constant static boolean member <code>value</code> == false
|
||||
//! <b>Note</b>: Non-standard extension used to implement `small_vector_allocator`.
|
||||
typedef see_documentation is_partially_propagable;
|
||||
//! Defines an allocator: Allocator::rebind<T>::other if such a type exists; otherwise, Allocator<T, Args>
|
||||
//! if Allocator is a class template instantiation of the form Allocator<U, Args>, where Args is zero or
|
||||
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
|
||||
//!
|
||||
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
|
||||
//! deduced by previously detailed rules.
|
||||
template <class T> using rebind_alloc = see_documentation;
|
||||
|
||||
//! In C++03 compilers <code>rebind_traits</code> is a struct derived from
|
||||
//! <code>allocator_traits<OtherAlloc></code>, where <code>OtherAlloc</code> is
|
||||
//! the allocator deduced by rules explained in <code>rebind_alloc</code>.
|
||||
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
|
||||
|
||||
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
|
||||
//! <code>type</code> is an allocator related to Allocator deduced deduced by rules explained in <code>rebind_alloc</code>.
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef see_documentation type; };
|
||||
#else
|
||||
//pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
pointer, value_type*)
|
||||
pointer;
|
||||
//const_pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
|
||||
rebind_pointer<const value_type>)
|
||||
const_pointer;
|
||||
//reference
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
reference, typename container_detail::unvoid_ref<value_type>::type)
|
||||
reference;
|
||||
//const_reference
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
const_reference, typename container_detail::unvoid_ref<const value_type>::type)
|
||||
const_reference;
|
||||
//void_pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
|
||||
rebind_pointer<void>)
|
||||
void_pointer;
|
||||
//const_void_pointer
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
|
||||
rebind_pointer<const void>)
|
||||
const_void_pointer;
|
||||
//difference_type
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
difference_type, std::ptrdiff_t)
|
||||
difference_type;
|
||||
//size_type
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
size_type, std::size_t)
|
||||
size_type;
|
||||
//propagate_on_container_copy_assignment
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
propagate_on_container_copy_assignment, container_detail::false_type)
|
||||
propagate_on_container_copy_assignment;
|
||||
//propagate_on_container_move_assignment
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
propagate_on_container_move_assignment, container_detail::false_type)
|
||||
propagate_on_container_move_assignment;
|
||||
//propagate_on_container_swap
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
propagate_on_container_swap, container_detail::false_type)
|
||||
propagate_on_container_swap;
|
||||
//is_always_equal
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
is_always_equal, container_detail::is_empty<Allocator>)
|
||||
is_always_equal;
|
||||
//is_partially_propagable
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
|
||||
is_partially_propagable, container_detail::false_type)
|
||||
is_partially_propagable;
|
||||
|
||||
//rebind_alloc & rebind_traits
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
//C++11
|
||||
template <typename T> using rebind_alloc = typename boost::intrusive::pointer_rebind<Allocator, T>::type;
|
||||
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
|
||||
#else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
//Some workaround for C++03 or C++11 compilers with no template aliases
|
||||
template <typename T>
|
||||
struct rebind_alloc : boost::intrusive::pointer_rebind<Allocator,T>::type
|
||||
{
|
||||
typedef typename boost::intrusive::pointer_rebind<Allocator,T>::type Base;
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <typename... Args>
|
||||
rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward<Args>(args)...) {}
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
|
||||
explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct rebind_traits
|
||||
: allocator_traits<typename boost::intrusive::pointer_rebind<Allocator, T>::type>
|
||||
{};
|
||||
#endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
|
||||
//portable_rebind_alloc
|
||||
template <class T>
|
||||
struct portable_rebind_alloc
|
||||
{ typedef typename boost::intrusive::pointer_rebind<Allocator, T>::type type; };
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Returns</b>: <code>a.allocate(n)</code>
|
||||
//!
|
||||
static pointer allocate(Allocator &a, size_type n)
|
||||
{ return a.allocate(n); }
|
||||
|
||||
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing
|
||||
static void deallocate(Allocator &a, pointer p, size_type n)
|
||||
{ a.deallocate(p, n); }
|
||||
|
||||
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>a.allocate(n)</code>
|
||||
static pointer allocate(Allocator &a, size_type n, const_void_pointer p)
|
||||
{
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_allocate
|
||||
<Allocator, const size_type, const const_void_pointer>::value;
|
||||
container_detail::bool_<value> flag;
|
||||
return allocator_traits::priv_allocate(flag, a, n, p);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>p->~T()</code>.
|
||||
template<class T>
|
||||
static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
typedef T* destroy_pointer;
|
||||
const bool value = boost::container::container_detail::
|
||||
has_member_function_callable_with_destroy
|
||||
<Allocator, const destroy_pointer>::value;
|
||||
container_detail::bool_<value> flag;
|
||||
allocator_traits::priv_destroy(flag, a, p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
|
||||
//! <code>numeric_limits<size_type>::max()</code>.
|
||||
static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
const bool value = allocator_traits_detail::has_max_size<Allocator, size_type (Allocator::*)() const>::value;
|
||||
container_detail::bool_<value> flag;
|
||||
return allocator_traits::priv_max_size(flag, a);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: <code>a.select_on_container_copy_construction()</code> if that expression is well-formed;
|
||||
//! otherwise, a.
|
||||
static BOOST_CONTAINER_DOC1ST(Allocator,
|
||||
typename container_detail::if_c
|
||||
< allocator_traits_detail::has_select_on_container_copy_construction<Allocator BOOST_MOVE_I Allocator (Allocator::*)() const>::value
|
||||
BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type)
|
||||
select_on_container_copy_construction(const Allocator &a)
|
||||
{
|
||||
const bool value = allocator_traits_detail::has_select_on_container_copy_construction
|
||||
<Allocator, Allocator (Allocator::*)() const>::value;
|
||||
container_detail::bool_<value> flag;
|
||||
return allocator_traits::priv_select_on_container_copy_construction(flag, a);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
|
||||
//! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
|
||||
template <class T, class ...Args>
|
||||
static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
static const bool value = ::boost::move_detail::and_
|
||||
< container_detail::is_not_std_allocator<Allocator>
|
||||
, boost::container::container_detail::has_member_function_callable_with_construct
|
||||
< Allocator, T*, Args... >
|
||||
>::value;
|
||||
container_detail::bool_<value> flag;
|
||||
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Returns</b>: <code>a.storage_is_unpropagable(p)</code> if is_partially_propagable::value is true; otherwise,
|
||||
//! <code>false</code>.
|
||||
static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
container_detail::bool_<is_partially_propagable::value> flag;
|
||||
return allocator_traits::priv_storage_is_unpropagable(flag, a, p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: <code>true</code> if <code>is_always_equal::value == true</code>, otherwise,
|
||||
//! <code>a == b</code>.
|
||||
static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
container_detail::bool_<is_always_equal::value> flag;
|
||||
return allocator_traits::priv_equal(flag, a, b);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
private:
|
||||
static pointer priv_allocate(container_detail::true_type, Allocator &a, size_type n, const_void_pointer p)
|
||||
{ return a.allocate(n, p); }
|
||||
|
||||
static pointer priv_allocate(container_detail::false_type, Allocator &a, size_type n, const_void_pointer)
|
||||
{ return a.allocate(n); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(container_detail::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ a.destroy(p); }
|
||||
|
||||
template<class T>
|
||||
static void priv_destroy(container_detail::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ p->~T(); (void)p; }
|
||||
|
||||
static size_type priv_max_size(container_detail::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return a.max_size(); }
|
||||
|
||||
static size_type priv_max_size(container_detail::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return size_type(-1)/sizeof(value_type); }
|
||||
|
||||
static Allocator priv_select_on_container_copy_construction(container_detail::true_type, const Allocator &a)
|
||||
{ return a.select_on_container_copy_construction(); }
|
||||
|
||||
static const Allocator &priv_select_on_container_copy_construction(container_detail::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return a; }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<class T, class ...Args>
|
||||
static void priv_construct(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
|
||||
{ a.construct( p, ::boost::forward<Args>(args)...); }
|
||||
|
||||
template<class T, class ...Args>
|
||||
static void priv_construct(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
|
||||
{ ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
public:
|
||||
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
|
||||
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
static const bool value = ::boost::move_detail::and_ \
|
||||
< container_detail::is_not_std_allocator<Allocator> \
|
||||
, boost::container::container_detail::has_member_function_callable_with_construct \
|
||||
< Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \
|
||||
>::value; \
|
||||
container_detail::bool_<value> flag;\
|
||||
(priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
|
||||
|
||||
private:
|
||||
/////////////////////////////////
|
||||
// priv_construct
|
||||
/////////////////////////////////
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \
|
||||
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{ a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\
|
||||
\
|
||||
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
static void priv_construct(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{ ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
|
||||
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class T>
|
||||
static void priv_construct(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
|
||||
{ ::new((void*)p, boost_container_new_t()) T; }
|
||||
|
||||
static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p)
|
||||
{ return a.storage_is_unpropagable(p); }
|
||||
|
||||
static bool priv_storage_is_unpropagable(container_detail::false_type, const Allocator &, pointer)
|
||||
{ return false; }
|
||||
|
||||
static bool priv_equal(container_detail::true_type, const Allocator &, const Allocator &)
|
||||
{ return true; }
|
||||
|
||||
static bool priv_equal(container_detail::false_type, const Allocator &a, const Allocator &b)
|
||||
{ return a == b; }
|
||||
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
|
||||
@@ -0,0 +1,317 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2014. 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_CONTAINER_FWD_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares the following containers:
|
||||
//! - boost::container::vector
|
||||
//! - boost::container::stable_vector
|
||||
//! - boost::container::static_vector
|
||||
//! - boost::container::small_vector
|
||||
//! - boost::container::slist
|
||||
//! - boost::container::list
|
||||
//! - boost::container::set
|
||||
//! - boost::container::multiset
|
||||
//! - boost::container::map
|
||||
//! - boost::container::multimap
|
||||
//! - boost::container::flat_set
|
||||
//! - boost::container::flat_multiset
|
||||
//! - boost::container::flat_map
|
||||
//! - boost::container::flat_multimap
|
||||
//! - boost::container::basic_string
|
||||
//! - boost::container::string
|
||||
//! - boost::container::wstring
|
||||
//!
|
||||
//! Forward declares the following allocators:
|
||||
//! - boost::container::allocator
|
||||
//! - boost::container::node_allocator
|
||||
//! - boost::container::adaptive_pool
|
||||
//!
|
||||
//! Forward declares the following polymorphic resource classes:
|
||||
//! - boost::container::pmr::memory_resource
|
||||
//! - boost::container::pmr::polymorphic_allocator
|
||||
//! - boost::container::pmr::monotonic_buffer_resource
|
||||
//! - boost::container::pmr::pool_options
|
||||
//! - boost::container::pmr::unsynchronized_pool_resource
|
||||
//! - boost::container::pmr::synchronized_pool_resource
|
||||
//!
|
||||
//! And finally it defines the following types
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//Std forward declarations
|
||||
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
namespace detail{
|
||||
//Create namespace to avoid compilation errors
|
||||
}}}
|
||||
|
||||
namespace boost{ namespace container{ namespace container_detail{
|
||||
namespace bi = boost::intrusive;
|
||||
namespace bid = boost::intrusive::detail;
|
||||
}}}
|
||||
|
||||
namespace boost{ namespace container{ namespace pmr{
|
||||
namespace bi = boost::intrusive;
|
||||
namespace bid = boost::intrusive::detail;
|
||||
}}}
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Containers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//! Enumeration used to configure ordered associative containers
|
||||
//! with a concrete tree implementation.
|
||||
enum tree_type_enum
|
||||
{
|
||||
red_black_tree,
|
||||
avl_tree,
|
||||
scapegoat_tree,
|
||||
splay_tree
|
||||
};
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template<class T>
|
||||
class new_allocator;
|
||||
|
||||
template <class T
|
||||
,class Allocator = new_allocator<T> >
|
||||
class vector;
|
||||
|
||||
template <class T
|
||||
,class Allocator = new_allocator<T> >
|
||||
class stable_vector;
|
||||
|
||||
template <class T, std::size_t Capacity>
|
||||
class static_vector;
|
||||
|
||||
template < class T, std::size_t N
|
||||
, class Allocator= new_allocator<T> >
|
||||
class small_vector;
|
||||
|
||||
template <class T
|
||||
,class Allocator = new_allocator<T> >
|
||||
class deque;
|
||||
|
||||
template <class T
|
||||
,class Allocator = new_allocator<T> >
|
||||
class list;
|
||||
|
||||
template <class T
|
||||
,class Allocator = new_allocator<T> >
|
||||
class slist;
|
||||
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt;
|
||||
|
||||
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<Key>
|
||||
,class Options = tree_assoc_defaults >
|
||||
class set;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<Key>
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multiset;
|
||||
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<std::pair<const Key, T> >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class map;
|
||||
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<std::pair<const Key, T> >
|
||||
,class Options = tree_assoc_defaults >
|
||||
class multimap;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<Key> >
|
||||
class flat_set;
|
||||
|
||||
template <class Key
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<Key> >
|
||||
class flat_multiset;
|
||||
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<std::pair<Key, T> > >
|
||||
class flat_map;
|
||||
|
||||
template <class Key
|
||||
,class T
|
||||
,class Compare = std::less<Key>
|
||||
,class Allocator = new_allocator<std::pair<Key, T> > >
|
||||
class flat_multimap;
|
||||
|
||||
template <class CharT
|
||||
,class Traits = std::char_traits<CharT>
|
||||
,class Allocator = new_allocator<CharT> >
|
||||
class basic_string;
|
||||
|
||||
typedef basic_string
|
||||
<char
|
||||
,std::char_traits<char>
|
||||
,new_allocator<char> >
|
||||
string;
|
||||
|
||||
typedef basic_string
|
||||
<wchar_t
|
||||
,std::char_traits<wchar_t>
|
||||
,new_allocator<wchar_t> >
|
||||
wstring;
|
||||
|
||||
static const std::size_t ADP_nodes_per_block = 256u;
|
||||
static const std::size_t ADP_max_free_blocks = 2u;
|
||||
static const std::size_t ADP_overhead_percent = 1u;
|
||||
static const std::size_t ADP_only_alignment = 0u;
|
||||
|
||||
template < class T
|
||||
, std::size_t NodesPerBlock = ADP_nodes_per_block
|
||||
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
|
||||
, std::size_t OverheadPercent = ADP_overhead_percent
|
||||
, unsigned Version = 2
|
||||
>
|
||||
class adaptive_pool;
|
||||
|
||||
template < class T
|
||||
, unsigned Version = 2
|
||||
, unsigned int AllocationDisableMask = 0>
|
||||
class allocator;
|
||||
|
||||
static const std::size_t NodeAlloc_nodes_per_block = 256u;
|
||||
|
||||
template
|
||||
< class T
|
||||
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block
|
||||
, std::size_t Version = 2>
|
||||
class node_allocator;
|
||||
|
||||
namespace pmr {
|
||||
|
||||
class memory_resource;
|
||||
|
||||
template<class T>
|
||||
class polymorphic_allocator;
|
||||
|
||||
class monotonic_buffer_resource;
|
||||
|
||||
struct pool_options;
|
||||
|
||||
template <class Allocator>
|
||||
class resource_adaptor_imp;
|
||||
|
||||
class unsynchronized_pool_resource;
|
||||
|
||||
class synchronized_pool_resource;
|
||||
|
||||
} //namespace pmr {
|
||||
|
||||
#else
|
||||
|
||||
//! Default options for tree-based associative containers
|
||||
//! - tree_type<red_black_tree>
|
||||
//! - optimize_size<true>
|
||||
typedef implementation_defined tree_assoc_defaults;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
struct ordered_range_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
static const ordered_range_t ordered_range = ordered_range_t();
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
struct ordered_unique_range_t
|
||||
: public ordered_range_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
|
||||
|
||||
//! Type used to tag that the inserted values
|
||||
//! should be default initialized
|
||||
struct default_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the inserted values
|
||||
//! should be default initialized
|
||||
static const default_init_t default_init = default_init_t();
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! Type used to tag that the inserted values
|
||||
//! should be value initialized
|
||||
struct value_init_t
|
||||
{};
|
||||
|
||||
//! Value used to tag that the inserted values
|
||||
//! should be value initialized
|
||||
static const value_init_t value_init = value_init_t();
|
||||
|
||||
namespace container_detail_really_deep_namespace {
|
||||
|
||||
//Otherwise, gcc issues a warning of previously defined
|
||||
//anonymous_instance and unique_instance
|
||||
struct dummy
|
||||
{
|
||||
dummy()
|
||||
{
|
||||
(void)ordered_range;
|
||||
(void)ordered_unique_range;
|
||||
(void)default_init;
|
||||
}
|
||||
};
|
||||
|
||||
} //detail_really_deep_namespace {
|
||||
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}} //namespace boost { namespace container {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
@@ -0,0 +1,41 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_ADDRESSOF_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <typename T>
|
||||
BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj)
|
||||
{
|
||||
return static_cast<T*>(
|
||||
static_cast<void*>(
|
||||
const_cast<char*>(
|
||||
&reinterpret_cast<const volatile char&>(obj)
|
||||
)));
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
|
||||
@@ -0,0 +1,477 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. 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_ADVANCED_INSERT_INT_HPP
|
||||
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// container
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/copy_move_algo.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
// move
|
||||
#include <boost/move/utility_core.hpp>
|
||||
// other
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
template<class Allocator, class FwdIt, class Iterator>
|
||||
struct move_insert_range_proxy
|
||||
{
|
||||
typedef typename allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
explicit move_insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
|
||||
(a, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
FwdIt first_;
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator, class FwdIt, class Iterator>
|
||||
struct insert_range_proxy
|
||||
{
|
||||
typedef typename allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
explicit insert_range_proxy(FwdIt first)
|
||||
: first_(first)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
|
||||
}
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n)
|
||||
{
|
||||
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
|
||||
}
|
||||
|
||||
FwdIt first_;
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_n_copies_proxy
|
||||
{
|
||||
typedef typename allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
explicit insert_n_copies_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
{
|
||||
for (; 0 < n; --n, ++p){
|
||||
*p = v_;
|
||||
}
|
||||
}
|
||||
|
||||
const value_type &v_;
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_value_initialized_n_proxy
|
||||
{
|
||||
typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
|
||||
typedef typename allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_value_init_alloc_n(a, n, p); }
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator, size_type) const
|
||||
{ BOOST_ASSERT(false); }
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_default_initialized_n_proxy
|
||||
{
|
||||
typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
|
||||
typedef typename allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{ boost::container::uninitialized_default_init_alloc_n(a, n, p); }
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator, size_type) const
|
||||
{ BOOST_ASSERT(false); }
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_copy_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
explicit insert_copy_proxy(const value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, iterator_to_raw_pointer(p), v_);
|
||||
}
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p =v_;
|
||||
}
|
||||
|
||||
const value_type &v_;
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_move_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
explicit insert_move_proxy(value_type &v)
|
||||
: v_(v)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) );
|
||||
}
|
||||
|
||||
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
*p = ::boost::move(v_);
|
||||
}
|
||||
|
||||
value_type &v_;
|
||||
};
|
||||
|
||||
template<class It, class Allocator>
|
||||
insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
|
||||
{
|
||||
return insert_move_proxy<Allocator, It>(v);
|
||||
}
|
||||
|
||||
template<class It, class Allocator>
|
||||
insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
|
||||
{
|
||||
return insert_copy_proxy<Allocator, It>(v);
|
||||
}
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class Allocator, class Iterator, class ...Args>
|
||||
struct insert_nonmovable_emplace_proxy
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
typedef typename alloc_traits::value_type value_type;
|
||||
|
||||
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
|
||||
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
template<std::size_t ...IdxPack>
|
||||
void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1); (void)n;
|
||||
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
|
||||
}
|
||||
|
||||
protected:
|
||||
tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator, class ...Args>
|
||||
struct insert_emplace_proxy
|
||||
: public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...>
|
||||
{
|
||||
typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;
|
||||
typedef typename base_t::value_type value_type;
|
||||
typedef typename base_t::size_type size_type;
|
||||
typedef typename base_t::index_tuple_t index_tuple_t;
|
||||
|
||||
explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
|
||||
: base_t(::boost::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
void copy_n_and_update(Allocator &a, Iterator p, size_type n)
|
||||
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
|
||||
|
||||
private:
|
||||
|
||||
template<std::size_t ...IdxPack>
|
||||
void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n ==1); (void)n;
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
|
||||
alloc_traits::construct(a, vp,
|
||||
::boost::forward<Args>(get<IdxPack>(this->args_))...);
|
||||
BOOST_TRY{
|
||||
*p = ::boost::move(*vp);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
alloc_traits::destroy(a, vp);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
alloc_traits::destroy(a, vp);
|
||||
}
|
||||
};
|
||||
|
||||
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
|
||||
: public insert_move_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
|
||||
: insert_move_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
|
||||
//compiler error C2752 ("more than one partial specialization matches").
|
||||
//Any problem is solvable with an extra layer of indirection? ;-)
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy<Allocator, Iterator
|
||||
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy<Allocator, Iterator
|
||||
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
|
||||
template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
struct insert_nonmovable_emplace_proxy##N\
|
||||
{\
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;\
|
||||
typedef typename alloc_traits::size_type size_type;\
|
||||
typedef typename alloc_traits::value_type value_type;\
|
||||
\
|
||||
explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
|
||||
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
|
||||
\
|
||||
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
|
||||
{\
|
||||
BOOST_ASSERT(n == 1); (void)n;\
|
||||
alloc_traits::construct(a, iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
|
||||
}\
|
||||
\
|
||||
void copy_n_and_update(Allocator &, Iterator, size_type)\
|
||||
{ BOOST_ASSERT(false); }\
|
||||
\
|
||||
protected:\
|
||||
BOOST_MOVE_MREF##N\
|
||||
};\
|
||||
\
|
||||
template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
struct insert_emplace_proxy_arg##N\
|
||||
: insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
|
||||
{\
|
||||
typedef insert_nonmovable_emplace_proxy##N\
|
||||
< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
|
||||
typedef typename base_t::value_type value_type;\
|
||||
typedef typename base_t::size_type size_type;\
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;\
|
||||
\
|
||||
explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
|
||||
: base_t(BOOST_MOVE_FWD##N){}\
|
||||
\
|
||||
void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
|
||||
{\
|
||||
BOOST_ASSERT(n == 1); (void)n;\
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
|
||||
BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\
|
||||
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));\
|
||||
alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
|
||||
BOOST_TRY{\
|
||||
*p = ::boost::move(*vp);\
|
||||
}\
|
||||
BOOST_CATCH(...){\
|
||||
alloc_traits::destroy(a, vp);\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
alloc_traits::destroy(a, vp);\
|
||||
}\
|
||||
};\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
|
||||
#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
|
||||
: public insert_move_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_move_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
#else //e.g. MSVC10 & MSVC11
|
||||
|
||||
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
|
||||
: public insert_move_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
|
||||
: insert_move_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
|
||||
//compiler error C2752 ("more than one partial specialization matches").
|
||||
//Any problem is solvable with an extra layer of indirection? ;-)
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy_arg1<Allocator, Iterator
|
||||
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template<class Allocator, class Iterator>
|
||||
struct insert_emplace_proxy_arg1<Allocator, Iterator
|
||||
, typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
|
||||
>
|
||||
: public insert_copy_proxy<Allocator, Iterator>
|
||||
{
|
||||
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
|
||||
: insert_copy_proxy<Allocator, Iterator>(v)
|
||||
{}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
||||
@@ -0,0 +1,35 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
||||
//
|
||||
// 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_DETAIL_ALGORITHM_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/algorithm.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
using boost::intrusive::algo_equal;
|
||||
using boost::intrusive::algo_lexicographical_compare;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
|
||||
@@ -0,0 +1,60 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_ALLOC_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// move
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
|
||||
{ boost::adl_move_swap(l, r); }
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
|
||||
BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
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_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
template<class AllocatorType>
|
||||
inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
|
||||
{ l = ::boost::move(r); }
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
||||
@@ -0,0 +1,58 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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_ALLOCATION_TYPE_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
enum allocation_type_v
|
||||
{
|
||||
// constants for allocation commands
|
||||
allocate_new_v = 0x01,
|
||||
expand_fwd_v = 0x02,
|
||||
expand_bwd_v = 0x04,
|
||||
// expand_both = expand_fwd | expand_bwd,
|
||||
// expand_or_new = allocate_new | expand_both,
|
||||
shrink_in_place_v = 0x08,
|
||||
nothrow_allocation_v = 0x10,
|
||||
zero_memory_v = 0x20,
|
||||
try_shrink_in_place_v = 0x40
|
||||
};
|
||||
|
||||
typedef unsigned int allocation_type;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
|
||||
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
|
||||
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
|
||||
static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
|
||||
static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
|
||||
static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
|
||||
static const allocation_type zero_memory = (allocation_type)zero_memory_v;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
||||
@@ -0,0 +1,162 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. 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_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp> //allocator_traits
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
|
||||
#include <boost/container/detail/version_type.hpp> //version_type
|
||||
#include <boost/container/detail/allocation_type.hpp> //allocation_type
|
||||
#include <boost/container/detail/mpl.hpp> //integral_constant
|
||||
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
|
||||
#include <boost/core/no_exceptions_support.hpp> //BOOST_TRY
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class Allocator, unsigned Version = boost::container::container_detail::version<Allocator>::value>
|
||||
struct allocator_version_traits
|
||||
{
|
||||
typedef ::boost::container::container_detail::integral_constant
|
||||
<unsigned, Version> alloc_version;
|
||||
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain;
|
||||
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
|
||||
//Node allocation interface
|
||||
static pointer allocate_one(Allocator &a)
|
||||
{ return a.allocate_one(); }
|
||||
|
||||
static void deallocate_one(Allocator &a, const pointer &p)
|
||||
{ a.deallocate_one(p); }
|
||||
|
||||
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
|
||||
{ return a.allocate_individual(n, m); }
|
||||
|
||||
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
|
||||
{ a.deallocate_individual(holder); }
|
||||
|
||||
static pointer allocation_command(Allocator &a, allocation_type command,
|
||||
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
|
||||
{ return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
|
||||
};
|
||||
|
||||
template<class Allocator>
|
||||
struct allocator_version_traits<Allocator, 1>
|
||||
{
|
||||
typedef ::boost::container::container_detail::integral_constant
|
||||
<unsigned, 1> alloc_version;
|
||||
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
|
||||
typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
|
||||
|
||||
typedef typename boost::intrusive::pointer_traits<pointer>::
|
||||
template rebind_pointer<void>::type void_ptr;
|
||||
typedef container_detail::basic_multiallocation_chain
|
||||
<void_ptr> multialloc_cached_counted;
|
||||
typedef boost::container::container_detail::
|
||||
transform_multiallocation_chain
|
||||
< multialloc_cached_counted, value_type> multiallocation_chain;
|
||||
|
||||
//Node allocation interface
|
||||
static pointer allocate_one(Allocator &a)
|
||||
{ return a.allocate(1); }
|
||||
|
||||
static void deallocate_one(Allocator &a, const pointer &p)
|
||||
{ a.deallocate(p, 1); }
|
||||
|
||||
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
|
||||
{
|
||||
size_type n = holder.size();
|
||||
typename multiallocation_chain::iterator it = holder.begin();
|
||||
while(n--){
|
||||
pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
|
||||
++it;
|
||||
a.deallocate(p, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct allocate_individual_rollback
|
||||
{
|
||||
allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
|
||||
: mr_a(a), mp_chain(&chain)
|
||||
{}
|
||||
|
||||
~allocate_individual_rollback()
|
||||
{
|
||||
if(mp_chain)
|
||||
allocator_version_traits::deallocate_individual(mr_a, *mp_chain);
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
mp_chain = 0;
|
||||
}
|
||||
|
||||
Allocator &mr_a;
|
||||
multiallocation_chain * mp_chain;
|
||||
};
|
||||
|
||||
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
|
||||
{
|
||||
allocate_individual_rollback rollback(a, m);
|
||||
while(n--){
|
||||
m.push_front(a.allocate(1));
|
||||
}
|
||||
rollback.release();
|
||||
}
|
||||
|
||||
static pointer allocation_command(Allocator &a, allocation_type command,
|
||||
size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
|
||||
{
|
||||
pointer ret = pointer();
|
||||
if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
|
||||
throw_logic_error("version 1 allocator without allocate_new flag");
|
||||
}
|
||||
else{
|
||||
BOOST_TRY{
|
||||
ret = a.allocate(prefer_in_recvd_out_size);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
if(!(command & nothrow_allocation)){
|
||||
BOOST_RETHROW
|
||||
}
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
reuse = pointer();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)
|
||||
@@ -0,0 +1,74 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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_DETAIL_COMPARE_FUNCTORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template<class Allocator>
|
||||
class equal_to_value
|
||||
{
|
||||
typedef typename Allocator::value_type value_type;
|
||||
const value_type &t_;
|
||||
|
||||
public:
|
||||
explicit equal_to_value(const value_type &t)
|
||||
: t_(t)
|
||||
{}
|
||||
|
||||
bool operator()(const value_type &t)const
|
||||
{ return t_ == t; }
|
||||
};
|
||||
|
||||
template<class Node, class Pred>
|
||||
struct value_to_node_compare
|
||||
: Pred
|
||||
{
|
||||
typedef Pred predicate_type;
|
||||
typedef Node node_type;
|
||||
|
||||
value_to_node_compare()
|
||||
: Pred()
|
||||
{}
|
||||
|
||||
explicit value_to_node_compare(Pred pred)
|
||||
: Pred(pred)
|
||||
{}
|
||||
|
||||
bool operator()(const Node &a, const Node &b) const
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data(), b.get_data()); }
|
||||
|
||||
bool operator()(const Node &a) const
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data()); }
|
||||
|
||||
bool operator()(const Node &a, const Node &b)
|
||||
{ return static_cast<Pred&>(*this)(a.get_data(), b.get_data()); }
|
||||
|
||||
bool operator()(const Node &a)
|
||||
{ return static_cast<Pred&>(*this)(a.get_data()); }
|
||||
|
||||
predicate_type & predicate() { return static_cast<predicate_type&>(*this); }
|
||||
const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); }
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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_CONTAINER_DETAIL_CONFIG_INCLUDED
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#endif //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4127) // conditional expression is constant
|
||||
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
|
||||
#pragma warning (disable : 4244) // possible loss of data
|
||||
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
|
||||
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
|
||||
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
|
||||
#pragma warning (disable : 4284) // odd return type for operator->
|
||||
#pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#pragma warning (disable : 4324) // structure was padded due to __declspec(align(
|
||||
#pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
|
||||
#pragma warning (disable : 4355) // "this" : used in base member initializer list
|
||||
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
|
||||
#pragma warning (disable : 4510) // default constructor could not be generated
|
||||
#pragma warning (disable : 4511) // copy constructor could not be generated
|
||||
#pragma warning (disable : 4512) // assignment operator could not be generated
|
||||
#pragma warning (disable : 4514) // unreferenced inline removed
|
||||
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
|
||||
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
|
||||
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result
|
||||
#pragma warning (disable : 4584) // X is already a base-class of Y
|
||||
#pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required
|
||||
#pragma warning (disable : 4671) // the copy constructor is inaccessible
|
||||
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
|
||||
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
|
||||
#pragma warning (disable : 4702) // unreachable code
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
||||
#pragma warning (disable : 4710) // function not inlined
|
||||
#pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
|
||||
#pragma warning (disable : 4711) // function selected for automatic inline expansion
|
||||
#pragma warning (disable : 4786) // identifier truncated in debug info
|
||||
#pragma warning (disable : 4996) // "function": was declared deprecated
|
||||
|
||||
#endif //BOOST_MSVC
|
||||
@@ -0,0 +1,13 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#if defined BOOST_MSVC
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
||||
//
|
||||
// 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_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/iterators.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//In place construction
|
||||
|
||||
template<class Allocator, class T, class InpIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source)
|
||||
{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); }
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest);
|
||||
}
|
||||
|
||||
template <class T, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
|
||||
}
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class Allocator, class T, class U, class EF, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.construct_in_place(a, dest);
|
||||
}
|
||||
|
||||
//Assignment
|
||||
|
||||
template<class DstIt, class InpIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source)
|
||||
{ *dest = *source; }
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U, D>)
|
||||
{
|
||||
container_detail::value_init<U> val;
|
||||
*dest = boost::move(val.get());
|
||||
}
|
||||
|
||||
template <class DstIt, class Difference>
|
||||
class default_init_construct_iterator;
|
||||
|
||||
template<class DstIt, class U, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U, D>)
|
||||
{
|
||||
U u;
|
||||
*dest = boost::move(u);
|
||||
}
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference>
|
||||
class emplace_iterator;
|
||||
|
||||
template<class DstIt, class U, class EF, class D>
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF, D> ei)
|
||||
{
|
||||
ei.assign_in_place(dest);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,378 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// 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_DESTROYERS_HPP
|
||||
#define BOOST_CONTAINER_DESTROYERS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_deallocator
|
||||
{
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::pointer pointer;
|
||||
typedef container_detail::integral_constant<unsigned,
|
||||
boost::container::container_detail::
|
||||
version<Allocator>::value> alloc_version;
|
||||
|
||||
private:
|
||||
void priv_deallocate(version_1)
|
||||
{ m_alloc.deallocate(m_ptr, 1); }
|
||||
|
||||
void priv_deallocate(version_2)
|
||||
{ m_alloc.deallocate_one(m_ptr); }
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
|
||||
|
||||
public:
|
||||
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
|
||||
scoped_deallocator(pointer p, Allocator& a)
|
||||
: m_ptr(p), m_alloc(a)
|
||||
{}
|
||||
|
||||
~scoped_deallocator()
|
||||
{ if (m_ptr)priv_deallocate(alloc_version()); }
|
||||
|
||||
scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
|
||||
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
|
||||
{ o.release(); }
|
||||
|
||||
pointer get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
void set(const pointer &p)
|
||||
{ m_ptr = p; }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
struct null_scoped_deallocator
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
typedef typename AllocTraits::pointer pointer;
|
||||
typedef typename AllocTraits::size_type size_type;
|
||||
|
||||
null_scoped_deallocator(pointer, Allocator&, size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
|
||||
pointer get() const
|
||||
{ return pointer(); }
|
||||
|
||||
void set(const pointer &)
|
||||
{}
|
||||
};
|
||||
|
||||
//!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 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) {}
|
||||
|
||||
~scoped_array_deallocator()
|
||||
{ if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
|
||||
private:
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
size_type m_length;
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
struct null_scoped_array_deallocator
|
||||
{
|
||||
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)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
struct scoped_destroy_deallocator
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
typedef typename AllocTraits::pointer pointer;
|
||||
typedef typename AllocTraits::size_type size_type;
|
||||
typedef container_detail::integral_constant<unsigned,
|
||||
boost::container::container_detail::
|
||||
version<Allocator>::value> alloc_version;
|
||||
|
||||
scoped_destroy_deallocator(pointer p, Allocator& a)
|
||||
: m_ptr(p), m_alloc(a) {}
|
||||
|
||||
~scoped_destroy_deallocator()
|
||||
{
|
||||
if(m_ptr){
|
||||
AllocTraits::destroy(m_alloc, container_detail::to_raw_pointer(m_ptr));
|
||||
priv_deallocate(m_ptr, alloc_version());
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
|
||||
private:
|
||||
|
||||
void priv_deallocate(const pointer &p, version_1)
|
||||
{ AllocTraits::deallocate(m_alloc, p, 1); }
|
||||
|
||||
void priv_deallocate(const pointer &p, version_2)
|
||||
{ m_alloc.deallocate_one(p); }
|
||||
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
};
|
||||
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_destructor_n
|
||||
{
|
||||
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;
|
||||
|
||||
scoped_destructor_n(pointer p, Allocator& a, size_type n)
|
||||
: m_p(p), m_a(a), m_n(n)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{ m_p = 0; }
|
||||
|
||||
void increment_size(size_type inc)
|
||||
{ m_n += inc; }
|
||||
|
||||
void increment_size_backwards(size_type inc)
|
||||
{ m_n += inc; m_p -= inc; }
|
||||
|
||||
void shrink_forward(size_type inc)
|
||||
{ m_n -= inc; m_p += inc; }
|
||||
|
||||
~scoped_destructor_n()
|
||||
{
|
||||
if(!m_p) return;
|
||||
value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
|
||||
while(m_n--){
|
||||
AllocTraits::destroy(m_a, raw_ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
pointer m_p;
|
||||
Allocator & m_a;
|
||||
size_type m_n;
|
||||
};
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct null_scoped_destructor_n
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
typedef typename AllocTraits::pointer pointer;
|
||||
typedef typename AllocTraits::size_type size_type;
|
||||
|
||||
null_scoped_destructor_n(pointer, Allocator&, size_type)
|
||||
{}
|
||||
|
||||
void increment_size(size_type)
|
||||
{}
|
||||
|
||||
void increment_size_backwards(size_type)
|
||||
{}
|
||||
|
||||
void shrink_forward(size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
template<class Allocator>
|
||||
class scoped_destructor
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
public:
|
||||
typedef typename Allocator::value_type value_type;
|
||||
scoped_destructor(Allocator &a, value_type *pv)
|
||||
: pv_(pv), a_(a)
|
||||
{}
|
||||
|
||||
~scoped_destructor()
|
||||
{
|
||||
if(pv_){
|
||||
AllocTraits::destroy(a_, pv_);
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{ pv_ = 0; }
|
||||
|
||||
|
||||
void set(value_type *ptr) { pv_ = ptr; }
|
||||
|
||||
value_type *get() const { return pv_; }
|
||||
|
||||
private:
|
||||
value_type *pv_;
|
||||
Allocator &a_;
|
||||
};
|
||||
|
||||
|
||||
template<class Allocator>
|
||||
class value_destructor
|
||||
{
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits;
|
||||
public:
|
||||
typedef typename Allocator::value_type value_type;
|
||||
value_destructor(Allocator &a, value_type &rv)
|
||||
: rv_(rv), a_(a)
|
||||
{}
|
||||
|
||||
~value_destructor()
|
||||
{
|
||||
AllocTraits::destroy(a_, &rv_);
|
||||
}
|
||||
|
||||
private:
|
||||
value_type &rv_;
|
||||
Allocator &a_;
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
class allocator_destroyer
|
||||
{
|
||||
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;
|
||||
|
||||
private:
|
||||
Allocator & a_;
|
||||
|
||||
private:
|
||||
void priv_deallocate(const pointer &p, version_1)
|
||||
{ AllocTraits::deallocate(a_,p, 1); }
|
||||
|
||||
void priv_deallocate(const pointer &p, version_2)
|
||||
{ a_.deallocate_one(p); }
|
||||
|
||||
public:
|
||||
explicit allocator_destroyer(Allocator &a)
|
||||
: a_(a)
|
||||
{}
|
||||
|
||||
void operator()(const pointer &p)
|
||||
{
|
||||
AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
this->priv_deallocate(p, alloc_version());
|
||||
}
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
class allocator_destroyer_and_chain_builder
|
||||
{
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain;
|
||||
|
||||
Allocator & a_;
|
||||
multiallocation_chain &c_;
|
||||
|
||||
public:
|
||||
allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
|
||||
: a_(a), c_(c)
|
||||
{}
|
||||
|
||||
void operator()(const typename Allocator::pointer &p)
|
||||
{
|
||||
allocator_traits<Allocator>::destroy(a_, container_detail::to_raw_pointer(p));
|
||||
c_.push_back(p);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
class allocator_multialloc_chain_node_deallocator
|
||||
{
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain;
|
||||
typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
|
||||
|
||||
Allocator & a_;
|
||||
multiallocation_chain c_;
|
||||
|
||||
public:
|
||||
allocator_multialloc_chain_node_deallocator(Allocator &a)
|
||||
: a_(a), c_()
|
||||
{}
|
||||
|
||||
chain_builder get_chain_builder()
|
||||
{ return chain_builder(a_, c_); }
|
||||
|
||||
~allocator_multialloc_chain_node_deallocator()
|
||||
{
|
||||
a_.deallocate_individual(c_);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
|
||||
@@ -0,0 +1,415 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_DISPATCH_USES_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/uses_allocator.hpp>
|
||||
|
||||
#include <boost/container/detail/addressof.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
|
||||
// Check if we can detect is_convertible using advanced SFINAE expressions
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list
|
||||
//! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html
|
||||
//! Thanks Mathias!
|
||||
|
||||
//With variadic templates, we need a single class to implement the trait
|
||||
template<class T, class ...Args>
|
||||
struct is_constructible
|
||||
{
|
||||
typedef char yes_type;
|
||||
struct no_type
|
||||
{ char padding[2]; };
|
||||
|
||||
template<std::size_t N>
|
||||
struct dummy;
|
||||
|
||||
template<class X>
|
||||
static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int);
|
||||
|
||||
template<class X>
|
||||
static no_type test(...);
|
||||
|
||||
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
|
||||
};
|
||||
|
||||
template <class T, class InnerAlloc, class ...Args>
|
||||
struct is_constructible_with_allocator_prefix
|
||||
: is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
|
||||
{};
|
||||
|
||||
#else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//Without advanced SFINAE expressions, we can't use is_constructible
|
||||
//so backup to constructible_with_allocator_xxx
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class T, class InnerAlloc, class ...Args>
|
||||
struct is_constructible_with_allocator_prefix
|
||||
: constructible_with_allocator_prefix<T>
|
||||
{};
|
||||
|
||||
template <class T, class InnerAlloc, class ...Args>
|
||||
struct is_constructible_with_allocator_suffix
|
||||
: constructible_with_allocator_suffix<T>
|
||||
{};
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
|
||||
struct is_constructible_with_allocator_prefix
|
||||
: constructible_with_allocator_prefix<T>
|
||||
{};
|
||||
|
||||
template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
|
||||
struct is_constructible_with_allocator_suffix
|
||||
: constructible_with_allocator_suffix<T>
|
||||
{};
|
||||
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#endif // #if !defined(BOOST_NO_SFINAE_EXPR)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, typename T
|
||||
, class ...Args
|
||||
>
|
||||
inline typename container_detail::enable_if_and
|
||||
< void
|
||||
, container_detail::is_not_pair<T>
|
||||
, container_detail::not_< uses_allocator<T, ArgAlloc> >
|
||||
>::type dispatch_uses_allocator
|
||||
( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
|
||||
{
|
||||
(void)arg_alloc;
|
||||
allocator_traits<ConstructAlloc>::construct(construct_alloc, p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// allocator_arg_t
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, typename T
|
||||
, class ...Args
|
||||
>
|
||||
inline typename container_detail::enable_if_and
|
||||
< void
|
||||
, container_detail::is_not_pair<T>
|
||||
, uses_allocator<T, ArgAlloc>
|
||||
, is_constructible_with_allocator_prefix<T, ArgAlloc, Args...>
|
||||
>::type dispatch_uses_allocator
|
||||
( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args)
|
||||
{
|
||||
allocator_traits<ConstructAlloc>::construct
|
||||
( construct_alloc, p, allocator_arg
|
||||
, ::boost::forward<ArgAlloc>(arg_alloc), ::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// allocator suffix
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, typename T
|
||||
, class ...Args
|
||||
>
|
||||
inline typename container_detail::enable_if_and
|
||||
< void
|
||||
, container_detail::is_not_pair<T>
|
||||
, uses_allocator<T, ArgAlloc>
|
||||
, container_detail::not_<is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> >
|
||||
>::type dispatch_uses_allocator
|
||||
( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
|
||||
{
|
||||
allocator_traits<ConstructAlloc>::construct
|
||||
(construct_alloc, p, ::boost::forward<Args>(args)..., ::boost::forward<ArgAlloc>(arg_alloc));
|
||||
}
|
||||
|
||||
#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
|
||||
template <typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
inline typename container_detail::enable_if_and\
|
||||
< void\
|
||||
, container_detail::is_not_pair<T>\
|
||||
, container_detail::not_<uses_allocator<T, ArgAlloc> >\
|
||||
>::type\
|
||||
dispatch_uses_allocator\
|
||||
(ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
(void)arg_alloc;\
|
||||
allocator_traits<ConstructAlloc>::construct(construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
|
||||
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
|
||||
|
||||
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
|
||||
template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
inline typename container_detail::enable_if_and\
|
||||
< void\
|
||||
, container_detail::is_not_pair<T>\
|
||||
, uses_allocator<T, ArgAlloc>\
|
||||
, is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>\
|
||||
>::type\
|
||||
dispatch_uses_allocator\
|
||||
(ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
allocator_traits<ConstructAlloc>::construct\
|
||||
(construct_alloc, p, allocator_arg, ::boost::forward<ArgAlloc>(arg_alloc) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
|
||||
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
|
||||
|
||||
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
|
||||
template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
inline typename container_detail::enable_if_and\
|
||||
< void\
|
||||
, container_detail::is_not_pair<T>\
|
||||
, uses_allocator<T, ArgAlloc>\
|
||||
, container_detail::not_<is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N> >\
|
||||
>::type\
|
||||
dispatch_uses_allocator\
|
||||
(ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
allocator_traits<ConstructAlloc>::construct\
|
||||
(construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, ::boost::forward<ArgAlloc>(arg_alloc));\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
|
||||
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
|
||||
|
||||
#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, typename Pair
|
||||
> inline
|
||||
BOOST_CONTAINER_DOC1ST(void, typename container_detail::enable_if<container_detail::is_pair<Pair> >::type)
|
||||
dispatch_uses_allocator
|
||||
( ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p)
|
||||
{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->first));
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->second));
|
||||
}
|
||||
BOOST_CATCH(...) {
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, container_detail::addressof(p->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class U, class V>
|
||||
BOOST_CONTAINER_DOC1ST(void, typename container_detail::enable_if<container_detail::is_pair<Pair> >::type)
|
||||
dispatch_uses_allocator
|
||||
( ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
|
||||
{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->first), ::boost::forward<U>(x));
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->second), ::boost::forward<V>(y));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, container_detail::addressof(p->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class Pair2>
|
||||
BOOST_CONTAINER_DOC1ST(void, typename container_detail::enable_if< container_detail::is_pair<Pair> >::type)
|
||||
dispatch_uses_allocator
|
||||
(ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p, Pair2& x)
|
||||
{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, x.first, x.second); }
|
||||
|
||||
template < typename ConstructAlloc
|
||||
, typename ArgAlloc
|
||||
, class Pair, class Pair2>
|
||||
typename container_detail::enable_if_and
|
||||
< void
|
||||
, container_detail::is_pair<Pair>
|
||||
, container_detail::not_<boost::move_detail::is_reference<Pair2> > >::type //This is needed for MSVC10 and ambiguous overloads
|
||||
dispatch_uses_allocator
|
||||
(ConstructAlloc & construct_alloc
|
||||
, BOOST_FWD_REF(ArgAlloc) arg_alloc
|
||||
, Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x)
|
||||
{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second)); }
|
||||
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair \
|
||||
, template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
typename container_detail::enable_if< container_detail::is_pair<Pair> >::type\
|
||||
dispatch_uses_allocator( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t\
|
||||
, BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
|
||||
{\
|
||||
(void)p; (void)q;\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, container_detail::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, container_detail::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, container_detail::addressof(pair->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
|
||||
|
||||
//piecewise construction from Std Tuple
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair
|
||||
, template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
|
||||
void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair
|
||||
, Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
|
||||
{
|
||||
(void)t1; (void)t2;
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...);
|
||||
BOOST_TRY{
|
||||
(dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, container_detail::addressof(pair->first));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair
|
||||
, template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
typename container_detail::enable_if< container_detail::is_pair<Pair> >::type
|
||||
dispatch_uses_allocator( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t
|
||||
, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
{
|
||||
(dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2
|
||||
, typename build_number_seq<sizeof...(Args1)>::type()
|
||||
, typename build_number_seq<sizeof...(Args2)>::type());
|
||||
}
|
||||
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
|
||||
//MSVC 2010 tuple implementation
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair\
|
||||
, template<class, class, class, class, class, class, class, class, class, class> class StdTuple\
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
typename container_detail::enable_if< container_detail::is_pair<Pair> >::type\
|
||||
dispatch_uses_allocator(ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
|
||||
{\
|
||||
(void)p; (void)q;\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, container_detail::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, container_detail::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, container_detail::addressof(pair->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
#if _VARIADIC_MAX >= 9
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
|
||||
#else
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
|
||||
#endif
|
||||
|
||||
//MSVC 2012 tuple implementation
|
||||
#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
|
||||
template< typename ConstructAlloc, typename ArgAlloc, class Pair\
|
||||
, template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
typename container_detail::enable_if< container_detail::is_pair<Pair> >::type\
|
||||
dispatch_uses_allocator\
|
||||
( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
|
||||
{\
|
||||
(void)p; (void)q;\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, container_detail::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
|
||||
BOOST_TRY{\
|
||||
(dispatch_uses_allocator)\
|
||||
(construct_alloc, arg_alloc, container_detail::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
|
||||
}\
|
||||
BOOST_CATCH(...) {\
|
||||
allocator_traits<ConstructAlloc>::destroy(construct_alloc, container_detail::addressof(pair->first));\
|
||||
BOOST_RETHROW\
|
||||
}\
|
||||
BOOST_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
|
||||
|
||||
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
} //namespace container_detail
|
||||
|
||||
}} // namespace boost { namespace container {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
|
||||
@@ -0,0 +1,40 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
||||
//
|
||||
// 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_DETAIL_ITERATOR_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATOR_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
using ::boost::intrusive::iterator_traits;
|
||||
using ::boost::intrusive::iterator_distance;
|
||||
using ::boost::intrusive::iterator_advance;
|
||||
using ::boost::intrusive::iterator;
|
||||
using ::boost::intrusive::iterator_enable_if_tag;
|
||||
using ::boost::intrusive::iterator_disable_if_tag;
|
||||
using ::boost::intrusive::iterator_arrow_result;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
@@ -0,0 +1,58 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <class T>
|
||||
inline T* iterator_to_pointer(T* i)
|
||||
{ return i; }
|
||||
|
||||
template <class Iterator>
|
||||
inline typename boost::container::iterator_traits<Iterator>::pointer
|
||||
iterator_to_pointer(const Iterator &i)
|
||||
{ return i.operator->(); }
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_to_element_ptr
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<Iterator>::pointer pointer;
|
||||
typedef typename boost::intrusive::pointer_traits<pointer>::element_type element_type;
|
||||
typedef element_type* type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
inline typename iterator_to_element_ptr<Iterator>::type
|
||||
iterator_to_raw_pointer(const Iterator &i)
|
||||
{
|
||||
return ::boost::intrusive::detail::to_raw_pointer
|
||||
( ::boost::container::container_detail::iterator_to_pointer(i) );
|
||||
}
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
|
||||
@@ -0,0 +1,875 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// 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_DETAIL_ITERATORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/value_init.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/intrusive/detail/reverse_iterator.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#else
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#endif
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class constant_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef constant_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit constant_iterator(const T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
constant_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
constant_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
constant_iterator operator++(int)
|
||||
{
|
||||
constant_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
constant_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
constant_iterator operator--(int)
|
||||
{
|
||||
constant_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
constant_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
constant_iterator operator+(Difference off) const
|
||||
{
|
||||
constant_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend constant_iterator operator+(Difference off, const constant_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
constant_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
constant_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
const T& operator[] (Difference ) const
|
||||
{ return dereference(); }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
private:
|
||||
const T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference>
|
||||
class value_init_construct_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef value_init_construct_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit value_init_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
value_init_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
value_init_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
value_init_construct_iterator operator++(int)
|
||||
{
|
||||
value_init_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
value_init_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
value_init_construct_iterator operator--(int)
|
||||
{
|
||||
value_init_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
value_init_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
value_init_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
value_init_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
value_init_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
value_init_construct_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
//const T& operator*() const;
|
||||
//const T& operator[](difference_type) const;
|
||||
//const T* operator->() const;
|
||||
|
||||
private:
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference>
|
||||
class default_init_construct_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef default_init_construct_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit default_init_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
default_init_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
default_init_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
default_init_construct_iterator operator++(int)
|
||||
{
|
||||
default_init_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
default_init_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
default_init_construct_iterator operator--(int)
|
||||
{
|
||||
default_init_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
default_init_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
default_init_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
default_init_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
default_init_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
default_init_construct_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
//const T& operator*() const;
|
||||
//const T& operator[](difference_type) const;
|
||||
//const T* operator->() const;
|
||||
|
||||
private:
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class repeat_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, T*, T&>
|
||||
{
|
||||
typedef repeat_iterator<T, Difference> this_type;
|
||||
public:
|
||||
explicit repeat_iterator(T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
repeat_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
this_type& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator++(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
this_type& operator--()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator--(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const this_type& i, const this_type& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const this_type& i, const this_type& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const this_type& i, const this_type& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const this_type& i, const this_type& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const this_type& i, const this_type& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const this_type& i, const this_type& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const this_type& i, const this_type& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
this_type& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
this_type operator+(Difference off) const
|
||||
{
|
||||
this_type other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend this_type operator+(Difference off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
this_type& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
this_type operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
T& operator[] (Difference ) const
|
||||
{ return dereference(); }
|
||||
|
||||
T *operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
|
||||
class emplace_iterator
|
||||
: public ::boost::container::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef emplace_iterator this_type;
|
||||
|
||||
public:
|
||||
typedef Difference difference_type;
|
||||
BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e)
|
||||
: m_num(1), m_pe(&e){}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE emplace_iterator()
|
||||
: m_num(0), m_pe(0){}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator++(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
this_type operator--(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
this_type operator+(difference_type off) const
|
||||
{
|
||||
this_type other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
private:
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
||||
//So comment them to catch bad uses
|
||||
const T& operator*() const;
|
||||
const T& operator[](difference_type) const;
|
||||
const T* operator->() const;
|
||||
|
||||
public:
|
||||
template<class Allocator>
|
||||
void construct_in_place(Allocator &a, T* ptr)
|
||||
{ (*m_pe)(a, ptr); }
|
||||
|
||||
template<class DestIt>
|
||||
void assign_in_place(DestIt dest)
|
||||
{ (*m_pe)(dest); }
|
||||
|
||||
private:
|
||||
difference_type m_num;
|
||||
EmplaceFunctor * m_pe;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void increment()
|
||||
{ --m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(difference_type n)
|
||||
{ m_num -= n; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const
|
||||
{ return difference_type(m_num - other.m_num); }
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class ...Args>
|
||||
struct emplace_functor
|
||||
{
|
||||
typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
emplace_functor(BOOST_FWD_REF(Args)... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
template<class Allocator, class T>
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)
|
||||
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
|
||||
|
||||
template<class DestIt>
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)
|
||||
{ emplace_functor::inplace_impl(dest, index_tuple_t()); }
|
||||
|
||||
private:
|
||||
template<class Allocator, class T, std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
allocator_traits<Allocator>::construct
|
||||
(a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
}
|
||||
|
||||
template<class DestIt, std::size_t ...IdxPack>
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const container_detail::index_tuple<IdxPack...>&)
|
||||
{
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;
|
||||
value_type && tmp= value_type(::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
||||
*dest = ::boost::move(tmp);
|
||||
}
|
||||
|
||||
container_detail::tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
template<class ...Args>
|
||||
struct emplace_functor_type
|
||||
{
|
||||
typedef emplace_functor<Args...> type;
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//Partial specializations cannot match argument list for primary template, so add an extra argument
|
||||
template <BOOST_MOVE_CLASSDFLT9, class Dummy = void>
|
||||
struct emplace_functor_type;
|
||||
|
||||
#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
struct emplace_functor##N\
|
||||
{\
|
||||
explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
|
||||
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
|
||||
\
|
||||
template<class Allocator, class T>\
|
||||
void operator()(Allocator &a, T *ptr)\
|
||||
{ allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
|
||||
\
|
||||
template<class DestIt>\
|
||||
void operator()(DestIt dest)\
|
||||
{\
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\
|
||||
BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), container_detail::value_init<value_type> tmp) ;\
|
||||
*dest = ::boost::move(const_cast<value_type &>(BOOST_MOVE_IF(N, tmp, tmp.get())));\
|
||||
}\
|
||||
\
|
||||
BOOST_MOVE_MREF##N\
|
||||
};\
|
||||
\
|
||||
template <BOOST_MOVE_CLASS##N>\
|
||||
struct emplace_functor_type<BOOST_MOVE_TARG##N>\
|
||||
{\
|
||||
typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\
|
||||
};\
|
||||
//
|
||||
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
|
||||
|
||||
#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
|
||||
|
||||
#endif
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<class T>
|
||||
struct has_iterator_category
|
||||
{
|
||||
struct two { char _[2]; };
|
||||
|
||||
template <typename X>
|
||||
static char test(int, typename X::iterator_category*);
|
||||
|
||||
template <typename X>
|
||||
static two test(int, ...);
|
||||
|
||||
static const bool value = (1 == sizeof(test<T>(0, 0)));
|
||||
};
|
||||
|
||||
|
||||
template<class T, bool = has_iterator_category<T>::value >
|
||||
struct is_input_iterator
|
||||
{
|
||||
static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_input_iterator<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_not_input_iterator
|
||||
{
|
||||
static const bool value = !is_input_iterator<T>::value;
|
||||
};
|
||||
|
||||
template<class T, bool = has_iterator_category<T>::value >
|
||||
struct is_forward_iterator
|
||||
{
|
||||
static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_forward_iterator<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T, bool = has_iterator_category<T>::value >
|
||||
struct is_bidirectional_iterator
|
||||
{
|
||||
static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_bidirectional_iterator<T, false>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class IINodeType>
|
||||
struct iiterator_node_value_type {
|
||||
typedef typename IINodeType::value_type type;
|
||||
};
|
||||
|
||||
template<class IIterator>
|
||||
struct iiterator_types
|
||||
{
|
||||
typedef typename IIterator::value_type it_value_type;
|
||||
typedef typename iiterator_node_value_type<it_value_type>::type value_type;
|
||||
typedef typename boost::container::iterator_traits<IIterator>::pointer it_pointer;
|
||||
typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type;
|
||||
typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
|
||||
template rebind_pointer<value_type>::type pointer;
|
||||
typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
|
||||
template rebind_pointer<const value_type>::type const_pointer;
|
||||
typedef typename ::boost::intrusive::
|
||||
pointer_traits<pointer>::reference reference;
|
||||
typedef typename ::boost::intrusive::
|
||||
pointer_traits<const_pointer>::reference const_reference;
|
||||
typedef typename IIterator::iterator_category iterator_category;
|
||||
};
|
||||
|
||||
template<class IIterator, bool IsConst>
|
||||
struct iterator_types
|
||||
{
|
||||
typedef typename ::boost::container::iterator
|
||||
< typename iiterator_types<IIterator>::iterator_category
|
||||
, typename iiterator_types<IIterator>::value_type
|
||||
, typename iiterator_types<IIterator>::difference_type
|
||||
, typename iiterator_types<IIterator>::const_pointer
|
||||
, typename iiterator_types<IIterator>::const_reference> type;
|
||||
};
|
||||
|
||||
template<class IIterator>
|
||||
struct iterator_types<IIterator, false>
|
||||
{
|
||||
typedef typename ::boost::container::iterator
|
||||
< typename iiterator_types<IIterator>::iterator_category
|
||||
, typename iiterator_types<IIterator>::value_type
|
||||
, typename iiterator_types<IIterator>::difference_type
|
||||
, typename iiterator_types<IIterator>::pointer
|
||||
, typename iiterator_types<IIterator>::reference> type;
|
||||
};
|
||||
|
||||
template<class IIterator, bool IsConst>
|
||||
class iterator_from_iiterator
|
||||
{
|
||||
typedef typename iterator_types<IIterator, IsConst>::type types_t;
|
||||
|
||||
public:
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
typedef typename types_t::difference_type difference_type;
|
||||
typedef typename types_t::iterator_category iterator_category;
|
||||
typedef typename types_t::value_type value_type;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator()
|
||||
: m_iit()
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(iit)
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_iit(other.get())
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ ++this->m_iit; return *this; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
iterator_from_iiterator result (*this);
|
||||
++this->m_iit;
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
//If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
|
||||
BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
|
||||
--this->m_iit; return *this;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
iterator_from_iiterator result (*this);
|
||||
--this->m_iit;
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return l.m_iit == r.m_iit; }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return !(l == r); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_iit->get_data(); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_iit; }
|
||||
|
||||
private:
|
||||
IIterator m_iit;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
using ::boost::intrusive::reverse_iterator;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
@@ -0,0 +1,37 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_MIN_MAX_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class T>
|
||||
const T &max_value(const T &a, const T &b)
|
||||
{ return a > b ? a : b; }
|
||||
|
||||
template<class T>
|
||||
const T &min_value(const T &a, const T &b)
|
||||
{ return a < b ? a : b; }
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
|
||||
@@ -0,0 +1,32 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015
|
||||
//
|
||||
// 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_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
||||
#
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
#
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
#
|
||||
#//Try to avoid including <string>, as it's quite big
|
||||
#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
|
||||
#include <iosfwd> //Dinkum libraries for MSVC define std::char_traits there
|
||||
#elif defined(BOOST_GNU_STDLIB)
|
||||
#include <bits/char_traits.h>
|
||||
#else
|
||||
#include <string> //Fallback
|
||||
#endif
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
||||
@@ -0,0 +1,86 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// 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_CONTAINER_DETAIL_MPL_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/detail/type_traits.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
using boost::move_detail::integral_constant;
|
||||
using boost::move_detail::true_type;
|
||||
using boost::move_detail::false_type;
|
||||
using boost::move_detail::enable_if_c;
|
||||
using boost::move_detail::enable_if;
|
||||
using boost::move_detail::enable_if_convertible;
|
||||
using boost::move_detail::disable_if_c;
|
||||
using boost::move_detail::disable_if;
|
||||
using boost::move_detail::disable_if_convertible;
|
||||
using boost::move_detail::is_convertible;
|
||||
using boost::move_detail::if_c;
|
||||
using boost::move_detail::if_;
|
||||
using boost::move_detail::identity;
|
||||
using boost::move_detail::bool_;
|
||||
using boost::move_detail::true_;
|
||||
using boost::move_detail::false_;
|
||||
using boost::move_detail::yes_type;
|
||||
using boost::move_detail::no_type;
|
||||
using boost::move_detail::bool_;
|
||||
using boost::move_detail::true_;
|
||||
using boost::move_detail::false_;
|
||||
using boost::move_detail::unvoid_ref;
|
||||
using boost::move_detail::and_;
|
||||
using boost::move_detail::or_;
|
||||
using boost::move_detail::not_;
|
||||
using boost::move_detail::enable_if_and;
|
||||
using boost::move_detail::disable_if_and;
|
||||
using boost::move_detail::enable_if_or;
|
||||
using boost::move_detail::disable_if_or;
|
||||
|
||||
template <class FirstType>
|
||||
struct select1st
|
||||
{
|
||||
typedef FirstType type;
|
||||
|
||||
template<class T>
|
||||
const type& operator()(const T& x) const
|
||||
{ return x.first; }
|
||||
|
||||
template<class T>
|
||||
type& operator()(T& x)
|
||||
{ return const_cast<type&>(x.first); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
// container
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/transform_iterator.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
// intrusive
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
// move
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class VoidPointer>
|
||||
class basic_multiallocation_chain
|
||||
{
|
||||
private:
|
||||
typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
|
||||
,bi::link_mode<bi::normal_link>
|
||||
> node;
|
||||
|
||||
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>
|
||||
, bi::cache_last<true>
|
||||
, bi::size_type<typename boost::container::container_detail::make_unsigned<difference_type>::type>
|
||||
> slist_impl_t;
|
||||
slist_impl_t slist_impl_;
|
||||
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<node_ptr> node_ptr_traits;
|
||||
|
||||
static node & to_node(const VoidPointer &p)
|
||||
{ return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
|
||||
|
||||
static VoidPointer from_node(node &n)
|
||||
{ return node_ptr_traits::pointer_to(n); }
|
||||
|
||||
static node_ptr to_node_ptr(const VoidPointer &p)
|
||||
{ return node_ptr_traits::static_cast_from(p); }
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
|
||||
|
||||
public:
|
||||
|
||||
typedef VoidPointer void_pointer;
|
||||
typedef typename slist_impl_t::iterator iterator;
|
||||
typedef typename slist_impl_t::size_type size_type;
|
||||
|
||||
basic_multiallocation_chain()
|
||||
: slist_impl_()
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
|
||||
: slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
|
||||
: slist_impl_(::boost::move(other.slist_impl_))
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
|
||||
{
|
||||
slist_impl_ = ::boost::move(other.slist_impl_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{ return slist_impl_.empty(); }
|
||||
|
||||
size_type size() const
|
||||
{ return slist_impl_.size(); }
|
||||
|
||||
iterator before_begin()
|
||||
{ return slist_impl_.before_begin(); }
|
||||
|
||||
iterator begin()
|
||||
{ return slist_impl_.begin(); }
|
||||
|
||||
iterator end()
|
||||
{ return slist_impl_.end(); }
|
||||
|
||||
iterator last()
|
||||
{ return slist_impl_.last(); }
|
||||
|
||||
void clear()
|
||||
{ slist_impl_.clear(); }
|
||||
|
||||
iterator insert_after(iterator it, void_pointer m)
|
||||
{ return slist_impl_.insert_after(it, to_node(m)); }
|
||||
|
||||
void push_front(const void_pointer &m)
|
||||
{ return slist_impl_.push_front(to_node(m)); }
|
||||
|
||||
void push_back(const void_pointer &m)
|
||||
{ return slist_impl_.push_back(to_node(m)); }
|
||||
|
||||
void_pointer pop_front()
|
||||
{
|
||||
node & n = slist_impl_.front();
|
||||
void_pointer ret = from_node(n);
|
||||
slist_impl_.pop_front();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); }
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
|
||||
|
||||
void erase_after(iterator before_b, iterator e, size_type n)
|
||||
{ slist_impl_.erase_after(before_b, e, n); }
|
||||
|
||||
void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
|
||||
{
|
||||
typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
|
||||
char_ptr elem = char_pointer_traits::static_cast_from(b);
|
||||
if(num_units){
|
||||
char_ptr prev_elem = elem;
|
||||
elem += unit_bytes;
|
||||
for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
|
||||
::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem);
|
||||
prev_elem = elem;
|
||||
}
|
||||
slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
|
||||
{ slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); }
|
||||
|
||||
void swap(basic_multiallocation_chain &x)
|
||||
{ slist_impl_.swap(x.slist_impl_); }
|
||||
|
||||
static iterator iterator_to(const void_pointer &p)
|
||||
{ return slist_impl_t::s_iterator_to(to_node(p)); }
|
||||
|
||||
std::pair<void_pointer, void_pointer> extract_data()
|
||||
{
|
||||
std::pair<void_pointer, void_pointer> ret
|
||||
(slist_impl_.begin().operator->()
|
||||
,slist_impl_.last().operator->());
|
||||
slist_impl_.clear();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct cast_functor
|
||||
{
|
||||
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)); }
|
||||
};
|
||||
|
||||
template<class MultiallocationChain, class T>
|
||||
class transform_multiallocation_chain
|
||||
: public MultiallocationChain
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
|
||||
//transform_multiallocation_chain(const transform_multiallocation_chain &);
|
||||
//transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
|
||||
|
||||
typedef typename MultiallocationChain::void_pointer void_pointer;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<void_pointer> void_pointer_traits;
|
||||
typedef typename void_pointer_traits::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::pointer_traits
|
||||
<pointer> pointer_traits;
|
||||
|
||||
static pointer cast(const void_pointer &p)
|
||||
{ return pointer_traits::static_cast_from(p); }
|
||||
|
||||
public:
|
||||
typedef transform_iterator
|
||||
< typename MultiallocationChain::iterator
|
||||
, container_detail::cast_functor <T> > iterator;
|
||||
typedef typename MultiallocationChain::size_type size_type;
|
||||
|
||||
transform_multiallocation_chain()
|
||||
: MultiallocationChain()
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
|
||||
: MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
|
||||
: MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
|
||||
{
|
||||
return static_cast<MultiallocationChain&>
|
||||
(this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
|
||||
}
|
||||
/*
|
||||
void push_front(const pointer &mem)
|
||||
{ holder_.push_front(mem); }
|
||||
|
||||
void push_back(const pointer &mem)
|
||||
{ return holder_.push_back(mem); }
|
||||
|
||||
void swap(transform_multiallocation_chain &other_chain)
|
||||
{ holder_.swap(other_chain.holder_); }
|
||||
|
||||
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
|
||||
{ holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n); }
|
||||
|
||||
void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
|
||||
{ holder_.incorporate_after(after_this.base(), b, before_e, n); }
|
||||
*/
|
||||
pointer pop_front()
|
||||
{ return cast(this->MultiallocationChain::pop_front()); }
|
||||
/*
|
||||
bool empty() const
|
||||
{ return holder_.empty(); }
|
||||
|
||||
iterator before_begin()
|
||||
{ return iterator(holder_.before_begin()); }
|
||||
*/
|
||||
iterator begin()
|
||||
{ return iterator(this->MultiallocationChain::begin()); }
|
||||
/*
|
||||
iterator end()
|
||||
{ return iterator(holder_.end()); }
|
||||
|
||||
iterator last()
|
||||
{ return iterator(holder_.last()); }
|
||||
|
||||
size_type size() const
|
||||
{ return holder_.size(); }
|
||||
|
||||
void clear()
|
||||
{ holder_.clear(); }
|
||||
*/
|
||||
iterator insert_after(iterator it, pointer m)
|
||||
{ return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
|
||||
|
||||
static iterator iterator_to(const pointer &p)
|
||||
{ return iterator(MultiallocationChain::iterator_to(p)); }
|
||||
|
||||
std::pair<pointer, pointer> extract_data()
|
||||
{
|
||||
std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data());
|
||||
return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
|
||||
}
|
||||
/*
|
||||
MultiallocationChain &extract_multiallocation_chain()
|
||||
{ return holder_; }*/
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
// namespace container_detail {
|
||||
// namespace container {
|
||||
// namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
@@ -0,0 +1,75 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_NEXT_CAPACITY_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// container
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/min_max.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
|
||||
|
||||
template<class SizeType, NextCapacityOption Option>
|
||||
struct next_capacity_calculator;
|
||||
|
||||
template<class SizeType>
|
||||
struct next_capacity_calculator<SizeType, NextCapacityDouble>
|
||||
{
|
||||
static SizeType get(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
const SizeType remaining = max_size - capacity;
|
||||
if ( remaining < n )
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
|
||||
const SizeType additional = max_value(n, capacity);
|
||||
return ( remaining < additional ) ? max_size : ( capacity + additional );
|
||||
}
|
||||
};
|
||||
|
||||
template<class SizeType>
|
||||
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
|
||||
{
|
||||
static SizeType get(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
const SizeType remaining = max_size - capacity;
|
||||
if ( remaining < n )
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3)
|
||||
return capacity + max_value(3*(capacity+1)/5, n);
|
||||
|
||||
if (capacity < m3*2)
|
||||
return capacity + max_value((capacity+1)/2, n);
|
||||
return max_size;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
|
||||
@@ -0,0 +1,419 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_NODE_ALLOC_HPP_
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
// container
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
// container/detail
|
||||
#include <boost/container/detail/addressof.hpp>
|
||||
#include <boost/container/detail/alloc_helpers.hpp>
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
||||
#include <boost/container/detail/construct_in_place.hpp>
|
||||
#include <boost/container/detail/destroyers.hpp>
|
||||
#include <boost/container/detail/iterator_to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
// intrusive
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/options.hpp>
|
||||
// move
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
// other
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
|
||||
|
||||
template<class Allocator, class ICont>
|
||||
struct node_alloc_holder
|
||||
{
|
||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
||||
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
( boost::container::container_detail::
|
||||
, ICont, value_compare, container_detail::nat) intrusive_value_compare;
|
||||
//In that case obtain the value predicate from the node predicate via predicate_type
|
||||
//if intrusive_value_compare is node_compare<>, nat otherwise
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
|
||||
( boost::container::container_detail::
|
||||
, intrusive_value_compare
|
||||
, predicate_type, container_detail::nat) value_compare;
|
||||
|
||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
typedef ICont intrusive_container;
|
||||
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 container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
|
||||
typedef Allocator 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,
|
||||
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;
|
||||
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
|
||||
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
||||
|
||||
public:
|
||||
|
||||
//Constructors for sequence containers
|
||||
node_alloc_holder()
|
||||
: members_()
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const ValAlloc &a)
|
||||
: members_(a)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const node_alloc_holder &x)
|
||||
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
|
||||
: members_(boost::move(x.node_alloc()))
|
||||
{ this->icont().swap(x.icont()); }
|
||||
|
||||
//Constructors for associative containers
|
||||
explicit node_alloc_holder(const value_compare &c, const ValAlloc &a)
|
||||
: members_(a, c)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const value_compare &c, const node_alloc_holder &x)
|
||||
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
|
||||
{}
|
||||
|
||||
explicit node_alloc_holder(const value_compare &c)
|
||||
: members_(c)
|
||||
{}
|
||||
|
||||
//helpers for move assignments
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const value_compare &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 allocator_traits_type::max_size(this->node_alloc()); }
|
||||
|
||||
NodePtr allocate_one()
|
||||
{ return AllocVersionTraits::allocate_one(this->node_alloc()); }
|
||||
|
||||
void deallocate_one(const NodePtr &p)
|
||||
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class ...Args>
|
||||
NodePtr create_node(Args &&...args)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
allocator_traits<NodeAlloc>::construct
|
||||
( this->node_alloc()
|
||||
, container_detail::addressof(p->m_data), boost::forward<Args>(args)...);
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
NodePtr create_node(BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
NodePtr p = this->allocate_one();\
|
||||
Deallocator node_deallocator(p, this->node_alloc());\
|
||||
allocator_traits<NodeAlloc>::construct\
|
||||
( this->node_alloc()\
|
||||
, container_detail::addressof(p->m_data)\
|
||||
BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
node_deallocator.release();\
|
||||
typedef typename Node::hook_type hook_type;\
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;\
|
||||
return (p);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL)
|
||||
#undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class 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(this->node_alloc(), container_detail::addressof(p->m_data), it);
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
template<class KeyConvertible>
|
||||
NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
NodeAlloc &na = this->node_alloc();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
node_allocator_traits_type::construct
|
||||
(na, container_detail::addressof(p->m_data.first), boost::forward<KeyConvertible>(key));
|
||||
BOOST_TRY{
|
||||
node_allocator_traits_type::construct(na, container_detail::addressof(p->m_data.second));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
node_allocator_traits_type::destroy(na, container_detail::addressof(p->m_data.first));
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
node_deallocator.release();
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
|
||||
return (p);
|
||||
}
|
||||
|
||||
void destroy_node(const NodePtr &nodep)
|
||||
{
|
||||
allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
|
||||
this->deallocate_one(nodep);
|
||||
}
|
||||
|
||||
void swap(node_alloc_holder &x)
|
||||
{
|
||||
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>
|
||||
void allocate_many_and_construct
|
||||
(FwdIterator beg, difference_type n, Inserter inserter)
|
||||
{
|
||||
if(n){
|
||||
typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//Try to allocate memory in a single block
|
||||
typedef typename multiallocation_chain::iterator multialloc_iterator;
|
||||
multiallocation_chain mem;
|
||||
NodeAlloc &nalloc = this->node_alloc();
|
||||
node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
|
||||
multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
|
||||
mem.clear();
|
||||
Node *p = 0;
|
||||
BOOST_TRY{
|
||||
Deallocator node_deallocator(NodePtr(), nalloc);
|
||||
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
|
||||
while(n--){
|
||||
p = container_detail::iterator_to_raw_pointer(itbeg);
|
||||
node_deallocator.set(p);
|
||||
++itbeg;
|
||||
//This can throw
|
||||
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
|
||||
sdestructor.set(p);
|
||||
++beg;
|
||||
//This does not throw
|
||||
typedef typename Node::hook_type hook_type;
|
||||
::new(static_cast<hook_type*>(p), boost_container_new_t()) hook_type;
|
||||
//This can throw in some containers (predicate might throw).
|
||||
//(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
|
||||
inserter(*p);
|
||||
sdestructor.set(0);
|
||||
}
|
||||
sdestructor.release();
|
||||
node_deallocator.release();
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
|
||||
node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
}
|
||||
|
||||
void clear(version_1)
|
||||
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
|
||||
|
||||
void clear(version_2)
|
||||
{
|
||||
typename NodeAlloc::multiallocation_chain chain;
|
||||
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
|
||||
this->icont().clear_and_dispose(builder);
|
||||
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
|
||||
if(!chain.empty())
|
||||
this->node_alloc().deallocate_individual(chain);
|
||||
}
|
||||
|
||||
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
|
||||
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
|
||||
|
||||
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
|
||||
{
|
||||
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
|
||||
NodeAlloc & nalloc = this->node_alloc();
|
||||
multiallocation_chain chain;
|
||||
allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
|
||||
icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
|
||||
nalloc.deallocate_individual(chain);
|
||||
return ret_it;
|
||||
}
|
||||
|
||||
template<class Key, class Comparator>
|
||||
size_type erase_key(const Key& k, const Comparator &comp, version_1)
|
||||
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
|
||||
|
||||
template<class Key, class Comparator>
|
||||
size_type erase_key(const Key& k, const Comparator &comp, version_2)
|
||||
{
|
||||
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
|
||||
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
|
||||
}
|
||||
|
||||
protected:
|
||||
struct cloner
|
||||
{
|
||||
explicit cloner(node_alloc_holder &holder)
|
||||
: m_holder(holder)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{ return m_holder.create_node(other.m_data); }
|
||||
|
||||
node_alloc_holder &m_holder;
|
||||
};
|
||||
|
||||
struct move_cloner
|
||||
{
|
||||
move_cloner(node_alloc_holder &holder)
|
||||
: m_holder(holder)
|
||||
{}
|
||||
|
||||
NodePtr operator()(Node &other)
|
||||
{ //Use m_data instead of get_data to allow moving const key in [multi]map
|
||||
return m_holder.create_node(::boost::move(other.m_data));
|
||||
}
|
||||
|
||||
node_alloc_holder &m_holder;
|
||||
};
|
||||
|
||||
struct members_holder
|
||||
: public NodeAlloc
|
||||
{
|
||||
private:
|
||||
members_holder(const members_holder&);
|
||||
members_holder & operator=(const members_holder&);
|
||||
|
||||
public:
|
||||
members_holder()
|
||||
: NodeAlloc(), m_icont()
|
||||
{}
|
||||
|
||||
template<class ConvertibleToAlloc>
|
||||
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 value_compare &c)
|
||||
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
|
||||
, m_icont(typename ICont::key_compare(c))
|
||||
{}
|
||||
|
||||
explicit members_holder(const value_compare &c)
|
||||
: NodeAlloc()
|
||||
, m_icont(typename ICont::key_compare(c))
|
||||
{}
|
||||
|
||||
//The intrusive container
|
||||
ICont m_icont;
|
||||
};
|
||||
|
||||
ICont &non_const_icont() const
|
||||
{ return const_cast<ICont&>(this->members_.m_icont); }
|
||||
|
||||
NodeAlloc &node_alloc()
|
||||
{ return static_cast<NodeAlloc &>(this->members_); }
|
||||
|
||||
const NodeAlloc &node_alloc() const
|
||||
{ return static_cast<const NodeAlloc &>(this->members_); }
|
||||
|
||||
members_holder members_;
|
||||
|
||||
public:
|
||||
ICont &icont()
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->members_.m_icont; }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
||||
@@ -0,0 +1,506 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// 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_CONTAINER_DETAIL_PAIR_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# include <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#endif
|
||||
#include <boost/move/adl_move_swap.hpp> //swap
|
||||
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include<boost/move/detail/fwd_macros.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace tuples {
|
||||
|
||||
struct null_type;
|
||||
|
||||
} //namespace tuples {
|
||||
} //namespace boost {
|
||||
|
||||
#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple marker
|
||||
namespace std { namespace tr1 { struct _Nil; }}
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
//MSVC 2012 tuple marker
|
||||
namespace std { struct _Nil; }
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <int Dummy = 0>
|
||||
struct std_piecewise_construct_holder
|
||||
{
|
||||
static ::std::piecewise_construct_t *dummy;
|
||||
};
|
||||
|
||||
template <int Dummy>
|
||||
::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy =
|
||||
reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers
|
||||
|
||||
typedef const std::piecewise_construct_t & piecewise_construct_t;
|
||||
|
||||
struct try_emplace_t{};
|
||||
|
||||
#else
|
||||
|
||||
//! The piecewise_construct_t struct is an empty structure type used as a unique type to
|
||||
//! disambiguate used to disambiguate between different functions that take two tuple arguments.
|
||||
typedef unspecified piecewise_construct_t;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! A instance of type
|
||||
//! piecewise_construct_t
|
||||
static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy);
|
||||
|
||||
///@cond
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
struct piecewise_construct_use
|
||||
{
|
||||
//Avoid warnings of unused "piecewise_construct"
|
||||
piecewise_construct_use()
|
||||
{ (void)&::boost::container::piecewise_construct; }
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair;
|
||||
|
||||
template <class T>
|
||||
struct is_pair
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_pair< pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_pair< std::pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_not_pair
|
||||
{
|
||||
static const bool value = !is_pair<T>::value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_std_pair
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_std_pair< std::pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
struct pair_nat;
|
||||
|
||||
template<typename T, typename U, typename V>
|
||||
void get(T); //to enable ADL
|
||||
|
||||
///@endcond
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(pair)
|
||||
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
|
||||
//Default constructor
|
||||
pair()
|
||||
: first(), second()
|
||||
{}
|
||||
|
||||
//pair copy assignment
|
||||
pair(const pair& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
|
||||
//pair move constructor
|
||||
pair(BOOST_RV_REF(pair) p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(const pair<D, S> &p)
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
//pair from two values
|
||||
pair(const T1 &t1, const T2 &t2)
|
||||
: first(t1)
|
||||
, second(t2)
|
||||
{}
|
||||
|
||||
template<class U, class V>
|
||||
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
|
||||
: first(::boost::forward<U>(u))
|
||||
, second(::boost::forward<V>(v))
|
||||
{}
|
||||
|
||||
//And now compatibility with std::pair
|
||||
pair(const std::pair<T1, T2>& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(const std::pair<D, S>& p)
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
|
||||
: first(::boost::move(p.first)), second(::boost::move(p.second))
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template< class KeyType, class ...Args>
|
||||
pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
|
||||
: first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
|
||||
{}
|
||||
#else
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\
|
||||
template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
|
||||
pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
|
||||
: first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
|
||||
{}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
|
||||
#undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
|
||||
|
||||
#endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
//piecewise construction from boost::tuple
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
|
||||
: first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
|
||||
|
||||
//piecewise construction from variadic tuple (with delegating constructors)
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
|
||||
private:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
|
||||
pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
|
||||
: first (::boost::forward<Args1>(get<Indexes1>(t1))...)
|
||||
, second(::boost::forward<Args2>(get<Indexes2>(t2))...)
|
||||
{ (void) t1; (void)t2; }
|
||||
|
||||
public:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
|
||||
{}
|
||||
# else
|
||||
//piecewise construction from variadic tuple (suboptimal, without delegating constructors)
|
||||
private:
|
||||
template<typename T, template<class ...> class Tuple, typename... Args>
|
||||
static T build_from_args(Tuple<Args...>&& t)
|
||||
{ return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type()); }
|
||||
|
||||
template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes>
|
||||
static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&)
|
||||
{ (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); }
|
||||
|
||||
public:
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2>
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
|
||||
: first (build_from_args<first_type> (::boost::move(t1)))
|
||||
, second (build_from_args<second_type>(::boost::move(t2)))
|
||||
{}
|
||||
# endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
||||
//MSVC 2010 tuple implementation
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
||||
#if _VARIADIC_MAX >= 9
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
|
||||
#else
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
|
||||
#endif
|
||||
|
||||
//MSVC 2012 tuple implementation
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
|
||||
template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
|
||||
pair( piecewise_construct_t\
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
|
||||
{ (void)p; (void)q; }\
|
||||
//
|
||||
BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
|
||||
#endif
|
||||
|
||||
//pair copy assignment
|
||||
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//pair move assignment
|
||||
pair& operator=(BOOST_RV_REF(pair) p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
typename ::boost::container::container_detail::disable_if_or
|
||||
< pair &
|
||||
, ::boost::container::container_detail::is_same<T1, D>
|
||||
, ::boost::container::container_detail::is_same<T2, S>
|
||||
>::type
|
||||
operator=(const pair<D, S>&p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
typename ::boost::container::container_detail::disable_if_or
|
||||
< pair &
|
||||
, ::boost::container::container_detail::is_same<T1, D>
|
||||
, ::boost::container::container_detail::is_same<T2, S>
|
||||
>::type
|
||||
operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
//std::pair copy assignment
|
||||
pair& operator=(const std::pair<T1, T2> &p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(const std::pair<D, S> &p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//std::pair move assignment
|
||||
pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
|
||||
{
|
||||
first = ::boost::move(p.first);
|
||||
second = ::boost::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//swap
|
||||
void swap(pair& p)
|
||||
{
|
||||
::boost::adl_move_swap(this->first, p.first);
|
||||
::boost::adl_move_swap(this->second, p.second);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(x.first == y.first && x.second == y.second); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(x.first < y.first ||
|
||||
(!(y.first < x.first) && x.second < y.second)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(!(x == y)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(!(x < y)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(!(y < x)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline pair<T1, T2> make_pair(T1 x, T2 y)
|
||||
{ return pair<T1, T2>(x, y); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template<class T1, class T2>
|
||||
struct has_move_emulation_enabled< ::boost::container::container_detail::pair<T1, T2> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
namespace move_detail{
|
||||
|
||||
template<class T>
|
||||
struct is_class_or_union;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class_or_union< ::boost::container::container_detail::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class_or_union< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_union;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_union< ::boost::container::container_detail::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_union< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_class;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class< ::boost::container::container_detail::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_class< std::pair<T1, T2> >
|
||||
//This specialization is needed to avoid instantiation of pair in
|
||||
//is_class, and allow recursive maps.
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace move_detail{
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
struct boost_container_new_t{};
|
||||
|
||||
//avoid including <new>
|
||||
inline void *operator new(std::size_t, void *p, boost_container_new_t)
|
||||
{ return p; }
|
||||
|
||||
inline void operator delete(void *, void *, boost_container_new_t)
|
||||
{}
|
||||
|
||||
#endif //BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
||||
@@ -0,0 +1,56 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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_DETAIL_STD_FWD_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Standard predeclarations
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/move/detail/std_ns_begin.hpp>
|
||||
BOOST_MOVE_STD_NS_BEG
|
||||
|
||||
template<class T>
|
||||
class allocator;
|
||||
|
||||
template<class T>
|
||||
struct less;
|
||||
|
||||
template<class T1, class T2>
|
||||
struct pair;
|
||||
|
||||
template<class T>
|
||||
struct char_traits;
|
||||
|
||||
struct input_iterator_tag;
|
||||
struct forward_iterator_tag;
|
||||
struct bidirectional_iterator_tag;
|
||||
struct random_access_iterator_tag;
|
||||
|
||||
template<class Container>
|
||||
class insert_iterator;
|
||||
|
||||
struct allocator_arg_t;
|
||||
|
||||
struct piecewise_construct_t;
|
||||
|
||||
BOOST_MOVE_STD_NS_END
|
||||
#include <boost/move/detail/std_ns_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
||||
@@ -0,0 +1,33 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_DETAIL_TO_RAW_POINTER_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/to_raw_pointer.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
using ::boost::intrusive::detail::to_raw_pointer;
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
|
||||
@@ -0,0 +1,180 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// 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_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template <class PseudoReference>
|
||||
struct operator_arrow_proxy
|
||||
{
|
||||
operator_arrow_proxy(const PseudoReference &px)
|
||||
: m_value(px)
|
||||
{}
|
||||
|
||||
typedef PseudoReference element_type;
|
||||
|
||||
PseudoReference* operator->() const { return &m_value; }
|
||||
|
||||
mutable PseudoReference m_value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct operator_arrow_proxy<T&>
|
||||
{
|
||||
operator_arrow_proxy(T &px)
|
||||
: m_value(px)
|
||||
{}
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
T* operator->() const { return const_cast<T*>(&m_value); }
|
||||
|
||||
T &m_value;
|
||||
};
|
||||
|
||||
template <class Iterator, class UnaryFunction>
|
||||
class transform_iterator
|
||||
: public UnaryFunction
|
||||
, public boost::container::iterator
|
||||
< typename Iterator::iterator_category
|
||||
, 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>
|
||||
{
|
||||
public:
|
||||
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
|
||||
: UnaryFunction(f), m_it(it)
|
||||
{}
|
||||
|
||||
explicit transform_iterator()
|
||||
: UnaryFunction(), m_it()
|
||||
{}
|
||||
|
||||
//Constructors
|
||||
transform_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
transform_iterator operator++(int)
|
||||
{
|
||||
transform_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
/*
|
||||
friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
*/
|
||||
friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
transform_iterator& operator+=(typename Iterator::difference_type off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
transform_iterator operator+(typename Iterator::difference_type off) const
|
||||
{
|
||||
transform_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
transform_iterator& operator-=(typename Iterator::difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
transform_iterator operator-(typename Iterator::difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
typename UnaryFunction::result_type operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
operator->() const
|
||||
{ return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
|
||||
|
||||
Iterator & base()
|
||||
{ return m_it; }
|
||||
|
||||
const Iterator & base() const
|
||||
{ return m_it; }
|
||||
|
||||
private:
|
||||
Iterator m_it;
|
||||
|
||||
void increment()
|
||||
{ ++m_it; }
|
||||
|
||||
void decrement()
|
||||
{ --m_it; }
|
||||
|
||||
bool equal(const transform_iterator &other) const
|
||||
{ return m_it == other.m_it; }
|
||||
|
||||
bool less(const transform_iterator &other) const
|
||||
{ return other.m_it < m_it; }
|
||||
|
||||
typename UnaryFunction::result_type dereference() const
|
||||
{ return UnaryFunction::operator()(*m_it); }
|
||||
|
||||
void advance(typename Iterator::difference_type n)
|
||||
{ boost::container::iterator_advance(m_it, n); }
|
||||
|
||||
typename Iterator::difference_type distance_to(const transform_iterator &other)const
|
||||
{ return boost::container::iterator_distance(other.m_it, m_it); }
|
||||
};
|
||||
|
||||
template <class Iterator, class UnaryFunc>
|
||||
transform_iterator<Iterator, UnaryFunc>
|
||||
make_transform_iterator(Iterator it, UnaryFunc fun)
|
||||
{
|
||||
return transform_iterator<Iterator, UnaryFunc>(it, fun);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// The alignment and Type traits implementation comes from
|
||||
// John Maddock's TypeTraits library.
|
||||
//
|
||||
// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/move/detail/type_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
using ::boost::move_detail::enable_if;
|
||||
using ::boost::move_detail::enable_if_and;
|
||||
using ::boost::move_detail::is_same;
|
||||
using ::boost::move_detail::is_different;
|
||||
using ::boost::move_detail::is_pointer;
|
||||
using ::boost::move_detail::add_reference;
|
||||
using ::boost::move_detail::add_const;
|
||||
using ::boost::move_detail::add_const_reference;
|
||||
using ::boost::move_detail::remove_const;
|
||||
using ::boost::move_detail::remove_reference;
|
||||
using ::boost::move_detail::make_unsigned;
|
||||
using ::boost::move_detail::is_floating_point;
|
||||
using ::boost::move_detail::is_integral;
|
||||
using ::boost::move_detail::is_enum;
|
||||
using ::boost::move_detail::is_pod;
|
||||
using ::boost::move_detail::is_empty;
|
||||
using ::boost::move_detail::is_trivially_destructible;
|
||||
using ::boost::move_detail::is_trivially_default_constructible;
|
||||
using ::boost::move_detail::is_trivially_copy_constructible;
|
||||
using ::boost::move_detail::is_trivially_move_constructible;
|
||||
using ::boost::move_detail::is_trivially_copy_assignable;
|
||||
using ::boost::move_detail::is_trivially_move_assignable;
|
||||
using ::boost::move_detail::is_nothrow_default_constructible;
|
||||
using ::boost::move_detail::is_nothrow_copy_constructible;
|
||||
using ::boost::move_detail::is_nothrow_move_constructible;
|
||||
using ::boost::move_detail::is_nothrow_copy_assignable;
|
||||
using ::boost::move_detail::is_nothrow_move_assignable;
|
||||
using ::boost::move_detail::is_nothrow_swappable;
|
||||
using ::boost::move_detail::alignment_of;
|
||||
using ::boost::move_detail::aligned_storage;
|
||||
using ::boost::move_detail::nat;
|
||||
using ::boost::move_detail::max_align_t;
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
@@ -0,0 +1,51 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
||||
//
|
||||
// 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_DETAIL_VALUE_INIT_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<class T>
|
||||
struct value_init
|
||||
{
|
||||
value_init()
|
||||
: m_t()
|
||||
{}
|
||||
|
||||
operator T &() { return m_t; }
|
||||
|
||||
T &get() { return m_t; }
|
||||
|
||||
T m_t;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
@@ -0,0 +1,163 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. 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_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template<typename... Values>
|
||||
class tuple;
|
||||
|
||||
template<> class tuple<>
|
||||
{};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
class tuple<Head, Tail...>
|
||||
: private tuple<Tail...>
|
||||
{
|
||||
typedef tuple<Tail...> inherited;
|
||||
|
||||
public:
|
||||
tuple()
|
||||
: inherited(), m_head()
|
||||
{}
|
||||
|
||||
template<class U, class ...Args>
|
||||
tuple(U &&u, Args && ...args)
|
||||
: inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u))
|
||||
{}
|
||||
|
||||
// Construct tuple from another tuple.
|
||||
template<typename... VValues>
|
||||
tuple(const tuple<VValues...>& other)
|
||||
: inherited(other.tail()), m_head(other.head())
|
||||
{}
|
||||
|
||||
template<typename... VValues>
|
||||
tuple& operator=(const tuple<VValues...>& other)
|
||||
{
|
||||
m_head = other.head();
|
||||
tail() = other.tail();
|
||||
return this;
|
||||
}
|
||||
|
||||
typename add_reference<Head>::type head() { return m_head; }
|
||||
typename add_reference<const Head>::type head() const { return m_head; }
|
||||
|
||||
inherited& tail() { return *this; }
|
||||
const inherited& tail() const { return *this; }
|
||||
|
||||
protected:
|
||||
Head m_head;
|
||||
};
|
||||
|
||||
|
||||
template<typename... Values>
|
||||
tuple<Values&&...> forward_as_tuple(Values&&... values)
|
||||
{ return tuple<Values&&...>(::boost::forward<Values>(values)...); }
|
||||
|
||||
template<int I, typename Tuple>
|
||||
struct tuple_element;
|
||||
|
||||
template<int I, typename Head, typename... Tail>
|
||||
struct tuple_element<I, tuple<Head, Tail...> >
|
||||
{
|
||||
typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
|
||||
};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
struct tuple_element<0, tuple<Head, Tail...> >
|
||||
{
|
||||
typedef Head type;
|
||||
};
|
||||
|
||||
template<int I, typename Tuple>
|
||||
class get_impl;
|
||||
|
||||
template<int I, typename Head, typename... Values>
|
||||
class get_impl<I, tuple<Head, Values...> >
|
||||
{
|
||||
typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
|
||||
typedef get_impl<I-1, tuple<Values...> > Next;
|
||||
|
||||
public:
|
||||
typedef typename add_reference<Element>::type type;
|
||||
typedef typename add_const_reference<Element>::type const_type;
|
||||
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
||||
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
||||
};
|
||||
|
||||
template<typename Head, typename... Values>
|
||||
class get_impl<0, tuple<Head, Values...> >
|
||||
{
|
||||
public:
|
||||
typedef typename add_reference<Head>::type type;
|
||||
typedef typename add_const_reference<Head>::type const_type;
|
||||
static type get(tuple<Head, Values...>& t) { return t.head(); }
|
||||
static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
|
||||
};
|
||||
|
||||
template<int I, typename... Values>
|
||||
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); }
|
||||
|
||||
template<int I, typename... Values>
|
||||
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
|
||||
// be used to "unpack" into comma-separated values
|
||||
// in a function call.
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
template<std::size_t...> struct index_tuple{ typedef index_tuple type; };
|
||||
|
||||
template<class S1, class S2> struct concat_index_tuple;
|
||||
|
||||
template<std::size_t... I1, std::size_t... I2>
|
||||
struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>>
|
||||
: index_tuple<I1..., (sizeof...(I1)+I2)...>{};
|
||||
|
||||
template<std::size_t N> struct build_number_seq;
|
||||
|
||||
template<std::size_t N>
|
||||
struct build_number_seq
|
||||
: concat_index_tuple<typename build_number_seq<N/2>::type
|
||||
,typename build_number_seq<N - N/2 >::type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template<> struct build_number_seq<0> : index_tuple<>{};
|
||||
template<> struct build_number_seq<1> : index_tuple<0>{};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace container_detail {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
@@ -0,0 +1,110 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 comes from N1953 document by Howard E. Hinnant
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace container_detail {
|
||||
|
||||
template <class T, unsigned V>
|
||||
struct version_type
|
||||
: public container_detail::integral_constant<unsigned, V>
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
version_type(const version_type<T, 0>&);
|
||||
};
|
||||
|
||||
namespace impl{
|
||||
|
||||
template <class T,
|
||||
bool = container_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
|
||||
struct extract_version
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct extract_version<T, true>
|
||||
{
|
||||
static const unsigned value = T::version::value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct has_version
|
||||
{
|
||||
private:
|
||||
struct two {char _[2];};
|
||||
template <class U> static two test(...);
|
||||
template <class U> static char test(const typename U::version*);
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == 1;
|
||||
void dummy(){}
|
||||
};
|
||||
|
||||
template <class T, bool = has_version<T>::value>
|
||||
struct version
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct version<T, true>
|
||||
{
|
||||
static const unsigned value = extract_version<T>::value;
|
||||
};
|
||||
|
||||
} //namespace impl
|
||||
|
||||
template <class T>
|
||||
struct version
|
||||
: public container_detail::integral_constant<unsigned, impl::version<T>::value>
|
||||
{};
|
||||
|
||||
template<class T, unsigned N>
|
||||
struct is_version
|
||||
{
|
||||
static const bool value =
|
||||
is_same< typename version<T>::type, integral_constant<unsigned, N> >::value;
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
typedef container_detail::integral_constant<unsigned, 0> version_0;
|
||||
typedef container_detail::integral_constant<unsigned, 1> version_1;
|
||||
typedef container_detail::integral_constant<unsigned, 2> version_2;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
@@ -0,0 +1,113 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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_DETAIL_WORKAROUND_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\
|
||||
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
|
||||
#define BOOST_CONTAINER_PERFECT_FORWARDING
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
|
||||
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
|
||||
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC_VERSION)
|
||||
# if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11)
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#elif defined(BOOST_MSVC)
|
||||
# if _MSC_FULL_VER < 180020827
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#elif defined(BOOST_CLANG)
|
||||
# if !__has_feature(cxx_delegating_constructors)
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_FALLTHOUGH)
|
||||
#define BOOST_CONTAINER_FALLTHOUGH
|
||||
#else
|
||||
#define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH;
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600))
|
||||
#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE
|
||||
#endif
|
||||
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
||||
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
|
||||
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
|
||||
|
||||
//Macros for memset optimization. In most platforms
|
||||
//memsetting pointers and floatings is safe and faster.
|
||||
//
|
||||
//If your platform does not offer these guarantees
|
||||
//define these to value zero.
|
||||
#ifndef BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO
|
||||
#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO 1
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_NULL
|
||||
#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL
|
||||
#endif
|
||||
|
||||
#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2
|
||||
#define BOOST_CONTAINER_I ,
|
||||
#define BOOST_CONTAINER_DOCIGN(T) T
|
||||
#define BOOST_CONTAINER_DOCONLY(T)
|
||||
|
||||
/*
|
||||
we need to import/export our code only if the user has specifically
|
||||
asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
|
||||
libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK
|
||||
if they want just this one to be dynamically liked:
|
||||
*/
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
||||
|
||||
/* export if this is our own source, otherwise import: */
|
||||
#ifdef BOOST_CONTAINER_SOURCE
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT
|
||||
#else
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT
|
||||
|
||||
#endif /* BOOST_CONTAINER_SOURCE */
|
||||
#else
|
||||
#define BOOST_CONTAINER_DECL
|
||||
#endif /* DYN_LINK */
|
||||
|
||||
//#define BOOST_CONTAINER_DISABLE_FORCEINLINE
|
||||
|
||||
#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE)
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE)
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
||||
#elif defined(BOOST_MSVC) && defined(_DEBUG)
|
||||
//"__forceinline" and MSVC seems to have some bugs in debug mode
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5)))
|
||||
//Older GCCs have problems with forceinline
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
||||
#else
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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_NEW_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
//!\file
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
|
||||
template<bool Value>
|
||||
struct new_allocator_bool
|
||||
{ static const bool value = Value; };
|
||||
|
||||
template<class T>
|
||||
class new_allocator;
|
||||
|
||||
/// @endcond
|
||||
|
||||
//! Specialization of new_allocator for void types
|
||||
template<>
|
||||
class new_allocator<void>
|
||||
{
|
||||
public:
|
||||
typedef void value_type;
|
||||
typedef void * pointer;
|
||||
typedef const void* const_pointer;
|
||||
//!A integral constant of type bool with value true
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
|
||||
//!A integral constant of type bool with value true
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
|
||||
// reference-to-void members are impossible
|
||||
|
||||
//!Obtains an new_allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef new_allocator< T2> other;
|
||||
};
|
||||
|
||||
//!Default constructor
|
||||
//!Never throws
|
||||
new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!Constructor from other new_allocator.
|
||||
//!Never throws
|
||||
new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!Constructor from related new_allocator.
|
||||
//!Never throws
|
||||
template<class T2>
|
||||
new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!Swaps two allocators, does nothing
|
||||
//!because this new_allocator is stateless
|
||||
friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!An new_allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return true; }
|
||||
|
||||
//!An new_allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
|
||||
//! This class is a reduced STL-compatible allocator that allocates memory using operator new
|
||||
template<class T>
|
||||
class new_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
//!A integral constant of type bool with value true
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
|
||||
//!A integral constant of type bool with value true
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
|
||||
|
||||
//!Obtains an new_allocator that allocates
|
||||
//!objects of type T2
|
||||
template<class T2>
|
||||
struct rebind
|
||||
{
|
||||
typedef new_allocator<T2> other;
|
||||
};
|
||||
|
||||
//!Default constructor
|
||||
//!Never throws
|
||||
new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!Constructor from other new_allocator.
|
||||
//!Never throws
|
||||
new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!Constructor from related new_allocator.
|
||||
//!Never throws
|
||||
template<class T2>
|
||||
new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!Allocates memory for an array of count elements.
|
||||
//!Throws std::bad_alloc if there is no enough memory
|
||||
pointer allocate(size_type count)
|
||||
{
|
||||
if(BOOST_UNLIKELY(count > this->max_size()))
|
||||
throw_bad_alloc();
|
||||
return static_cast<T*>(::operator new(count*sizeof(T)));
|
||||
}
|
||||
|
||||
//!Deallocates previously allocated memory.
|
||||
//!Never throws
|
||||
void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ ::operator delete((void*)ptr); }
|
||||
|
||||
//!Returns the maximum number of elements that could be allocated.
|
||||
//!Never throws
|
||||
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return size_type(-1)/sizeof(T); }
|
||||
|
||||
//!Swaps two allocators, does nothing
|
||||
//!because this new_allocator is stateless
|
||||
friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{}
|
||||
|
||||
//!An new_allocator always compares to true, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return true; }
|
||||
|
||||
//!An new_allocator always compares to false, as memory allocated with one
|
||||
//!instance can be deallocated by another instance
|
||||
friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP
|
||||
@@ -0,0 +1,396 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016. 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_NODE_HANDLE_HPP
|
||||
#define BOOST_CONTAINER_NODE_HANDLE_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/placement_new.hpp>
|
||||
#include <boost/container/detail/to_raw_pointer.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
|
||||
|
||||
//!\file
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
///@cond
|
||||
|
||||
template<class Value, class KeyMapped, bool keymapped_is_void = container_detail::is_same<KeyMapped, void>::value>
|
||||
struct node_handle_keymapped_traits
|
||||
{
|
||||
typedef Value key_type;
|
||||
typedef Value mapped_type;
|
||||
};
|
||||
|
||||
template<class Value, class KeyMapped>
|
||||
struct node_handle_keymapped_traits<Value, KeyMapped, false>
|
||||
{
|
||||
typedef typename KeyMapped::key_type key_type;
|
||||
typedef typename KeyMapped::mapped_type mapped_type;
|
||||
};
|
||||
|
||||
///@endcond
|
||||
|
||||
//! A node_handle is an object that accepts ownership of a single element from an associative container.
|
||||
//! It may be used to transfer that ownership to another container with compatible nodes. Containers
|
||||
//! with compatible nodes have the same node handle type. Elements may be transferred in either direction
|
||||
//! between container types in the same row:.
|
||||
//!
|
||||
//! Container types with compatible nodes
|
||||
//!
|
||||
//! map<K, T, C1, A> <-> map<K, T, C2, A>
|
||||
//!
|
||||
//! map<K, T, C1, A> <-> multimap<K, T, C2, A>
|
||||
//!
|
||||
//! set<K, C1, A> <-> set<K, C2, A>
|
||||
//!
|
||||
//! set<K, C1, A> <-> multiset<K, C2, A>
|
||||
//!
|
||||
//! If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container
|
||||
//! when the element was extracted. If a node handle is empty, it contains no allocator.
|
||||
template <class NodeType, class Value, class Allocator, class KeyMapped = void>
|
||||
class node_handle
|
||||
{
|
||||
typedef node_handle_keymapped_traits<Value, KeyMapped> keymapped_t;
|
||||
|
||||
public:
|
||||
typedef Value value_type;
|
||||
typedef typename keymapped_t::key_type key_type;
|
||||
typedef typename keymapped_t::mapped_type mapped_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef NodeType container_node_type;
|
||||
|
||||
///@cond
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle)
|
||||
|
||||
typedef allocator_traits<allocator_type> ator_traits;
|
||||
typedef typename ator_traits::template portable_rebind_alloc
|
||||
<container_node_type>::type nallocator_type;
|
||||
typedef allocator_traits<nallocator_type> node_ator_traits;
|
||||
typedef typename node_ator_traits::pointer node_pointer;
|
||||
typedef ::boost::aligned_storage
|
||||
<sizeof(allocator_type), boost::alignment_of<nallocator_type>::value> nalloc_storage_t;
|
||||
|
||||
node_pointer m_ptr;
|
||||
nalloc_storage_t m_nalloc_storage;
|
||||
|
||||
void move_construct_alloc(nallocator_type &al)
|
||||
{ ::new(m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(al)); }
|
||||
|
||||
void destroy_node()
|
||||
{
|
||||
node_ator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(m_ptr));
|
||||
node_ator_traits::deallocate(this->node_alloc(), m_ptr, 1u);
|
||||
}
|
||||
|
||||
template<class OtherNodeHandle>
|
||||
void move_construct_end(OtherNodeHandle &nh)
|
||||
{
|
||||
if(m_ptr){
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) allocator_type(::boost::move(nh.node_alloc()));
|
||||
nh.destroy_alloc();
|
||||
nh.get_node_pointer() = node_pointer();
|
||||
}
|
||||
BOOST_ASSERT(nh.empty());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void destroy_alloc()
|
||||
{ static_cast<allocator_type*>(m_nalloc_storage.address())->~allocator_type(); }
|
||||
|
||||
node_pointer &get_node_pointer()
|
||||
{ return m_ptr; }
|
||||
|
||||
nallocator_type &node_alloc()
|
||||
{ return *static_cast<nallocator_type*>(m_nalloc_storage.address()); }
|
||||
|
||||
node_pointer release()
|
||||
{
|
||||
node_pointer p(m_ptr);
|
||||
m_ptr = node_pointer();
|
||||
if(p)
|
||||
this->destroy_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
///@endcond
|
||||
|
||||
public:
|
||||
//! <b>Effects</b>: Initializes m_ptr to nullptr.
|
||||
//!
|
||||
//! <b>Postcondition</b>: this->empty()
|
||||
BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT
|
||||
: m_ptr(), m_nalloc_storage()
|
||||
{ BOOST_ASSERT(this->empty()); }
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with p.
|
||||
//! If p != nullptr copy constructs internal allocator al.
|
||||
node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT
|
||||
: m_ptr(p), m_nalloc_storage()
|
||||
{
|
||||
if(m_ptr){
|
||||
::new (m_nalloc_storage.address(), boost_container_new_t()) nallocator_type(al);
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with a related nh's internal pointer
|
||||
//! and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
|
||||
//! allocator with nh's internal allocator and destroy nh's internal allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: nh.empty()
|
||||
//!
|
||||
//! <b>Note</b>: Two node_handle's are related if only one of KeyMapped template parameter
|
||||
//! of a node handle is void.
|
||||
template<class KeyMapped2>
|
||||
node_handle( BOOST_RV_REF_BEG node_handle<NodeType, Value, Allocator, KeyMapped2> BOOST_RV_REF_END nh
|
||||
, typename container_detail::enable_if_c
|
||||
< ((unsigned)container_detail::is_same<KeyMapped, void>::value +
|
||||
(unsigned)container_detail::is_same<KeyMapped2, void>::value) == 1u
|
||||
>::type* = 0)
|
||||
: m_ptr(nh.get_node_pointer()), m_nalloc_storage()
|
||||
{ this->move_construct_end(nh); }
|
||||
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with nh's internal pointer
|
||||
//! and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
|
||||
//! allocator with nh's internal allocator and destroy nh's internal allocator.
|
||||
//!
|
||||
//! <b>Postcondition</b>: nh.empty()
|
||||
node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT
|
||||
: m_ptr(nh.m_ptr), m_nalloc_storage()
|
||||
{ this->move_construct_end(nh); }
|
||||
|
||||
//! <b>Effects</b>: If !this->empty(), destroys the value_type subobject in the container_node_type object
|
||||
//! pointed to by c by calling allocator_traits<impl_defined>::destroy, then deallocates m_ptr by calling
|
||||
//! ator_traits::rebind_traits<container_node_type>::deallocate.
|
||||
~node_handle () BOOST_NOEXCEPT
|
||||
{
|
||||
if(!this->empty()){
|
||||
this->destroy_node();
|
||||
this->destroy_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: Either this->empty(), or ator_traits::propagate_on_container_move_assignment is true, or
|
||||
//! node_alloc() == nh.node_alloc().
|
||||
//!
|
||||
//! <b>Effects</b>: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object
|
||||
//! pointed to by m_ptr by calling ator_traits::destroy, then deallocates m_ptr by calling ator_-
|
||||
//! traits::rebind_traits<container_node_type>::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty()
|
||||
//! or ator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to
|
||||
//! node_alloc(). Assigns nullptr to nh.m_ptr and assigns nullopt to nh.node_alloc().
|
||||
//! <b>Returns</b>: *this.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
node_handle & operator=(BOOST_RV_REF(node_handle) nh)
|
||||
{
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_move_assignment::value
|
||||
|| ator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
|
||||
bool const was_this_non_null = !this->empty();
|
||||
bool const was_nh_non_null = !nh.empty();
|
||||
|
||||
if(was_nh_non_null){
|
||||
if(was_this_non_null){
|
||||
this->destroy_node();
|
||||
if(ator_traits::propagate_on_container_move_assignment::value){
|
||||
this->node_alloc() = ::boost::move(nh.node_alloc());
|
||||
}
|
||||
}
|
||||
else{
|
||||
this->move_construct_alloc(nh.node_alloc());
|
||||
}
|
||||
m_ptr = nh.m_ptr;
|
||||
nh.m_ptr = node_pointer();
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
else if(was_this_non_null){
|
||||
this->destroy_node();
|
||||
this->destroy_alloc();
|
||||
m_ptr = node_pointer();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A reference to the value_type subobject in the container_node_type object pointed to by m_ptr
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
value_type& value() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((container_detail::is_same<KeyMapped, void>::value));
|
||||
BOOST_ASSERT(!empty());
|
||||
return m_ptr->get_data();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A non-const reference to the key_type member of the value_type subobject in the
|
||||
//! container_node_type object pointed to by m_ptr.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Requires</b>: Modifying the key through the returned reference is permitted.
|
||||
key_type& key() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!container_detail::is_same<KeyMapped, void>::value));
|
||||
BOOST_ASSERT(!empty());
|
||||
return const_cast<key_type &>(KeyMapped().key_of_value(m_ptr->get_data()));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A reference to the mapped_type member of the value_type subobject
|
||||
//! in the container_node_type object pointed to by m_ptr
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
mapped_type& mapped() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!container_detail::is_same<KeyMapped, void>::value));
|
||||
BOOST_ASSERT(!empty());
|
||||
return KeyMapped().mapped_of_value(m_ptr->get_data());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: empty() == false.
|
||||
//!
|
||||
//! <b>Returns</b>: A copy of the internally hold allocator.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
allocator_type get_allocator() const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
return this->node_alloc();
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: m_ptr != nullptr.
|
||||
//!
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
BOOST_CONTAINER_FORCEINLINE explicit operator bool
|
||||
#else
|
||||
private: struct bool_conversion {int for_bool; int for_arg(); }; typedef int bool_conversion::* explicit_bool_arg;
|
||||
public: BOOST_CONTAINER_FORCEINLINE operator explicit_bool_arg
|
||||
#endif
|
||||
()const BOOST_NOEXCEPT
|
||||
{ return m_ptr ? &bool_conversion::for_bool : explicit_bool_arg(0); }
|
||||
|
||||
//! <b>Returns</b>: m_ptr == nullptr.
|
||||
//!
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
{
|
||||
return !this->m_ptr;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: this->empty(), or nh.empty(), or ator_traits::propagate_on_container_swap is true, or
|
||||
//! node_alloc() == nh.node_alloc().
|
||||
//!
|
||||
//! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or ator_traits::propagate_on_-
|
||||
//! container_swap is true calls swap(node_alloc(), nh.node_alloc()).
|
||||
void swap(node_handle &nh)
|
||||
BOOST_NOEXCEPT_IF(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value)
|
||||
{
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || ator_traits::propagate_on_container_swap::value
|
||||
|| ator_traits::equal(node_alloc(), nh.node_alloc()));
|
||||
|
||||
bool const was_this_non_null = !this->empty();
|
||||
bool const was_nh_non_null = !nh.empty();
|
||||
|
||||
if(was_nh_non_null){
|
||||
if(was_this_non_null){
|
||||
if(ator_traits::propagate_on_container_swap){
|
||||
::boost::adl_move_swap(this->node_alloc(), nh.node_alloc());
|
||||
}
|
||||
}
|
||||
else{
|
||||
this->move_construct_alloc(nh.node_alloc());
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
}
|
||||
else if(was_this_non_null){
|
||||
nh.move_construct_alloc(this->node_alloc());
|
||||
nh.destroy_alloc();
|
||||
}
|
||||
::boost::adl_move_swap(m_ptr, nh.m_ptr);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: x.swap(y).
|
||||
//!
|
||||
friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y)))
|
||||
{ x.swap(y); }
|
||||
};
|
||||
|
||||
//! A class template used to describe the results of inserting a
|
||||
//! Container::node_type in a Container with unique keys.
|
||||
//! Includes at least the following non-static public data members:
|
||||
//!
|
||||
//! <ul><li>bool inserted</li>;
|
||||
//! <li>Iterator position</li>;
|
||||
//! <li>NodeType node</li></ul>
|
||||
//!
|
||||
//! This type is MoveConstructible, MoveAssignable, DefaultConstructible,
|
||||
//! Destructible, and lvalues of that type are swappable
|
||||
template<class Iterator, class NodeType>
|
||||
struct insert_return_type_base
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_base)
|
||||
|
||||
public:
|
||||
insert_return_type_base()
|
||||
: inserted(false), position(), node()
|
||||
{}
|
||||
|
||||
insert_return_type_base(BOOST_RV_REF(insert_return_type_base) other)
|
||||
: inserted(other.inserted), position(other.position), node(boost::move(other.node))
|
||||
{}
|
||||
|
||||
template<class RelatedIt, class RelatedNode>
|
||||
insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) node)
|
||||
: inserted(insert), position(it), node(boost::move(node))
|
||||
{}
|
||||
|
||||
insert_return_type_base & operator=(BOOST_RV_REF(insert_return_type_base) other)
|
||||
{
|
||||
inserted = other.inserted;
|
||||
position = other.position;
|
||||
node = boost::move(other.node);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool inserted;
|
||||
Iterator position;
|
||||
NodeType node;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_NODE_HANDLE_HPP
|
||||
@@ -0,0 +1,80 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013
|
||||
//
|
||||
// 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_OPTIONS_HPP
|
||||
#define BOOST_CONTAINER_OPTIONS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
#include <boost/intrusive/pack_options.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<tree_type_enum TreeType, bool OptimizeSize>
|
||||
struct tree_opt
|
||||
{
|
||||
static const boost::container::tree_type_enum tree_type = TreeType;
|
||||
static const bool optimize_size = OptimizeSize;
|
||||
};
|
||||
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//!This option setter specifies the underlying tree type
|
||||
//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
|
||||
|
||||
//!This option setter specifies if node size is optimized
|
||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::set, \c boost::container::multiset
|
||||
//! \c boost::container::map and \c boost::container::multimap.
|
||||
//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct tree_assoc_options
|
||||
{
|
||||
/// @cond
|
||||
typedef typename ::boost::intrusive::pack_options
|
||||
< tree_assoc_defaults,
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
||||
@@ -0,0 +1,907 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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-2013. 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)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/scoped_allocator_fwd.hpp>
|
||||
#include <boost/container/detail/dispatch_uses_allocator.hpp>
|
||||
|
||||
#include <boost/container/detail/mpl.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/move/adl_move_swap.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template <typename Allocator>
|
||||
struct is_scoped_allocator_imp
|
||||
{
|
||||
typedef char yes_type;
|
||||
struct no_type{ char dummy[2]; };
|
||||
|
||||
template <typename T>
|
||||
static yes_type test(typename T::outer_allocator_type*);
|
||||
|
||||
template <typename T>
|
||||
static int test(...);
|
||||
|
||||
static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0)));
|
||||
};
|
||||
|
||||
template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
|
||||
struct outermost_allocator_type_impl
|
||||
{
|
||||
typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
|
||||
typedef typename outermost_allocator_type_impl<outer_type>::type type;
|
||||
};
|
||||
|
||||
template<class MaybeScopedAlloc>
|
||||
struct outermost_allocator_type_impl<MaybeScopedAlloc, false>
|
||||
{
|
||||
typedef MaybeScopedAlloc type;
|
||||
};
|
||||
|
||||
template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
|
||||
struct outermost_allocator_imp
|
||||
{
|
||||
typedef MaybeScopedAlloc type;
|
||||
|
||||
static type &get(MaybeScopedAlloc &a)
|
||||
{ return a; }
|
||||
|
||||
static const type &get(const MaybeScopedAlloc &a)
|
||||
{ return a; }
|
||||
};
|
||||
|
||||
template<class MaybeScopedAlloc>
|
||||
struct outermost_allocator_imp<MaybeScopedAlloc, true>
|
||||
{
|
||||
typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
|
||||
typedef typename outermost_allocator_type_impl<outer_type>::type type;
|
||||
|
||||
static type &get(MaybeScopedAlloc &a)
|
||||
{ return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
|
||||
|
||||
static const type &get(const MaybeScopedAlloc &a)
|
||||
{ return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
template <typename Allocator>
|
||||
struct is_scoped_allocator
|
||||
: container_detail::is_scoped_allocator_imp<Allocator>
|
||||
{};
|
||||
|
||||
template <typename Allocator>
|
||||
struct outermost_allocator
|
||||
: container_detail::outermost_allocator_imp<Allocator>
|
||||
{};
|
||||
|
||||
template <typename Allocator>
|
||||
typename outermost_allocator<Allocator>::type &
|
||||
get_outermost_allocator(Allocator &a)
|
||||
{ return outermost_allocator<Allocator>::get(a); }
|
||||
|
||||
template <typename Allocator>
|
||||
const typename outermost_allocator<Allocator>::type &
|
||||
get_outermost_allocator(const Allocator &a)
|
||||
{ return outermost_allocator<Allocator>::get(a); }
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename OuterAlloc, class ...InnerAllocs>
|
||||
class scoped_allocator_adaptor_base
|
||||
: public OuterAlloc
|
||||
{
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
|
||||
|
||||
public:
|
||||
template <class OuterA2>
|
||||
struct rebind_base
|
||||
{
|
||||
typedef scoped_allocator_adaptor_base<OuterA2, InnerAllocs...> other;
|
||||
};
|
||||
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef scoped_allocator_adaptor
|
||||
<OuterAlloc, InnerAllocs...> scoped_allocator_type;
|
||||
typedef container_detail::bool_<
|
||||
outer_traits_type::propagate_on_container_copy_assignment::value ||
|
||||
inner_allocator_type::propagate_on_container_copy_assignment::value
|
||||
> propagate_on_container_copy_assignment;
|
||||
typedef container_detail::bool_<
|
||||
outer_traits_type::propagate_on_container_move_assignment::value ||
|
||||
inner_allocator_type::propagate_on_container_move_assignment::value
|
||||
> propagate_on_container_move_assignment;
|
||||
typedef container_detail::bool_<
|
||||
outer_traits_type::propagate_on_container_swap::value ||
|
||||
inner_allocator_type::propagate_on_container_swap::value
|
||||
> propagate_on_container_swap;
|
||||
typedef container_detail::bool_<
|
||||
outer_traits_type::is_always_equal::value &&
|
||||
inner_allocator_type::is_always_equal::value
|
||||
> is_always_equal;
|
||||
|
||||
scoped_allocator_adaptor_base()
|
||||
{}
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
|
||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
||||
, m_inner(args...)
|
||||
{}
|
||||
|
||||
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
|
||||
: outer_allocator_type(other.outer_allocator())
|
||||
, m_inner(other.inner_allocator())
|
||||
{}
|
||||
|
||||
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
||||
: outer_allocator_type(::boost::move(other.outer_allocator()))
|
||||
, m_inner(::boost::move(other.inner_allocator()))
|
||||
{}
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base
|
||||
(const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
|
||||
: outer_allocator_type(other.outer_allocator())
|
||||
, m_inner(other.inner_allocator())
|
||||
{}
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base
|
||||
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base
|
||||
<OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
|
||||
: outer_allocator_type(other.outer_allocator())
|
||||
, m_inner(other.inner_allocator())
|
||||
{}
|
||||
|
||||
public:
|
||||
struct internal_type_t{};
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base
|
||||
( internal_type_t
|
||||
, BOOST_FWD_REF(OuterA2) outerAlloc
|
||||
, const inner_allocator_type &inner)
|
||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
||||
, m_inner(inner)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
scoped_allocator_adaptor_base &operator=
|
||||
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
||||
{
|
||||
outer_allocator_type::operator=(other.outer_allocator());
|
||||
m_inner = other.inner_allocator();
|
||||
return *this;
|
||||
}
|
||||
|
||||
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
||||
{
|
||||
outer_allocator_type::operator=(boost::move(other.outer_allocator()));
|
||||
m_inner = ::boost::move(other.inner_allocator());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(scoped_allocator_adaptor_base &r)
|
||||
{
|
||||
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
|
||||
boost::adl_move_swap(this->m_inner, r.inner_allocator());
|
||||
}
|
||||
|
||||
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
|
||||
{ l.swap(r); }
|
||||
|
||||
inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return m_inner; }
|
||||
|
||||
inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return m_inner; }
|
||||
|
||||
outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<outer_allocator_type&>(*this); }
|
||||
|
||||
const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<const outer_allocator_type&>(*this); }
|
||||
|
||||
scoped_allocator_type select_on_container_copy_construction() const
|
||||
{
|
||||
return scoped_allocator_type
|
||||
(internal_type_t()
|
||||
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
|
||||
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
inner_allocator_type m_inner;
|
||||
};
|
||||
|
||||
#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//Let's add a dummy first template parameter to allow creating
|
||||
//specializations up to maximum InnerAlloc count
|
||||
template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
|
||||
class scoped_allocator_adaptor_base;
|
||||
|
||||
//Specializations for the adaptor with InnerAlloc allocators
|
||||
|
||||
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\
|
||||
template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
|
||||
class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
|
||||
: public OuterAlloc\
|
||||
{\
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;\
|
||||
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\
|
||||
\
|
||||
public:\
|
||||
template <class OuterA2>\
|
||||
struct rebind_base\
|
||||
{\
|
||||
typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\
|
||||
};\
|
||||
\
|
||||
typedef OuterAlloc outer_allocator_type;\
|
||||
typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\
|
||||
typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;\
|
||||
typedef container_detail::bool_<\
|
||||
outer_traits_type::propagate_on_container_copy_assignment::value ||\
|
||||
inner_allocator_type::propagate_on_container_copy_assignment::value\
|
||||
> propagate_on_container_copy_assignment;\
|
||||
typedef container_detail::bool_<\
|
||||
outer_traits_type::propagate_on_container_move_assignment::value ||\
|
||||
inner_allocator_type::propagate_on_container_move_assignment::value\
|
||||
> propagate_on_container_move_assignment;\
|
||||
typedef container_detail::bool_<\
|
||||
outer_traits_type::propagate_on_container_swap::value ||\
|
||||
inner_allocator_type::propagate_on_container_swap::value\
|
||||
> propagate_on_container_swap;\
|
||||
\
|
||||
typedef container_detail::bool_<\
|
||||
outer_traits_type::is_always_equal::value &&\
|
||||
inner_allocator_type::is_always_equal::value\
|
||||
> is_always_equal;\
|
||||
\
|
||||
scoped_allocator_adaptor_base(){}\
|
||||
\
|
||||
template <class OuterA2>\
|
||||
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
|
||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
|
||||
, m_inner(BOOST_MOVE_ARG##N)\
|
||||
{}\
|
||||
\
|
||||
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\
|
||||
: outer_allocator_type(other.outer_allocator())\
|
||||
, m_inner(other.inner_allocator())\
|
||||
{}\
|
||||
\
|
||||
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
|
||||
: outer_allocator_type(::boost::move(other.outer_allocator()))\
|
||||
, m_inner(::boost::move(other.inner_allocator()))\
|
||||
{}\
|
||||
\
|
||||
template <class OuterA2>\
|
||||
scoped_allocator_adaptor_base\
|
||||
(const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\
|
||||
: outer_allocator_type(other.outer_allocator())\
|
||||
, m_inner(other.inner_allocator())\
|
||||
{}\
|
||||
\
|
||||
template <class OuterA2>\
|
||||
scoped_allocator_adaptor_base\
|
||||
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\
|
||||
: outer_allocator_type(other.outer_allocator())\
|
||||
, m_inner(other.inner_allocator())\
|
||||
{}\
|
||||
\
|
||||
public:\
|
||||
struct internal_type_t{};\
|
||||
\
|
||||
template <class OuterA2>\
|
||||
scoped_allocator_adaptor_base\
|
||||
( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\
|
||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
|
||||
, m_inner(inner)\
|
||||
{}\
|
||||
\
|
||||
public:\
|
||||
scoped_allocator_adaptor_base &operator=\
|
||||
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
|
||||
{\
|
||||
outer_allocator_type::operator=(other.outer_allocator());\
|
||||
m_inner = other.inner_allocator();\
|
||||
return *this;\
|
||||
}\
|
||||
\
|
||||
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
|
||||
{\
|
||||
outer_allocator_type::operator=(boost::move(other.outer_allocator()));\
|
||||
m_inner = ::boost::move(other.inner_allocator());\
|
||||
return *this;\
|
||||
}\
|
||||
\
|
||||
void swap(scoped_allocator_adaptor_base &r)\
|
||||
{\
|
||||
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\
|
||||
boost::adl_move_swap(this->m_inner, r.inner_allocator());\
|
||||
}\
|
||||
\
|
||||
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
|
||||
{ l.swap(r); }\
|
||||
\
|
||||
inner_allocator_type& inner_allocator()\
|
||||
{ return m_inner; }\
|
||||
\
|
||||
inner_allocator_type const& inner_allocator() const\
|
||||
{ return m_inner; }\
|
||||
\
|
||||
outer_allocator_type & outer_allocator()\
|
||||
{ return static_cast<outer_allocator_type&>(*this); }\
|
||||
\
|
||||
const outer_allocator_type &outer_allocator() const\
|
||||
{ return static_cast<const outer_allocator_type&>(*this); }\
|
||||
\
|
||||
scoped_allocator_type select_on_container_copy_construction() const\
|
||||
{\
|
||||
return scoped_allocator_type\
|
||||
(internal_type_t()\
|
||||
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\
|
||||
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\
|
||||
);\
|
||||
}\
|
||||
private:\
|
||||
inner_allocator_type m_inner;\
|
||||
};\
|
||||
//!
|
||||
BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE)
|
||||
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE
|
||||
|
||||
#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
#define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true
|
||||
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9
|
||||
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9
|
||||
#else
|
||||
#define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE
|
||||
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs...
|
||||
#define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs
|
||||
#endif
|
||||
|
||||
//Specialization for adaptor without any InnerAlloc
|
||||
template <typename OuterAlloc>
|
||||
class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>
|
||||
: public OuterAlloc
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
|
||||
public:
|
||||
|
||||
template <class U>
|
||||
struct rebind_base
|
||||
{
|
||||
typedef scoped_allocator_adaptor_base
|
||||
<typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
|
||||
BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other;
|
||||
};
|
||||
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;
|
||||
typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
|
||||
typedef inner_allocator_type scoped_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef typename outer_traits_type::
|
||||
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
||||
typedef typename outer_traits_type::
|
||||
propagate_on_container_move_assignment propagate_on_container_move_assignment;
|
||||
typedef typename outer_traits_type::
|
||||
propagate_on_container_swap propagate_on_container_swap;
|
||||
typedef typename outer_traits_type::
|
||||
is_always_equal is_always_equal;
|
||||
|
||||
scoped_allocator_adaptor_base()
|
||||
{}
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
|
||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
||||
{}
|
||||
|
||||
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
|
||||
: outer_allocator_type(other.outer_allocator())
|
||||
{}
|
||||
|
||||
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
||||
: outer_allocator_type(::boost::move(other.outer_allocator()))
|
||||
{}
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base
|
||||
(const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other)
|
||||
: outer_allocator_type(other.outer_allocator())
|
||||
{}
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base
|
||||
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
|
||||
: outer_allocator_type(other.outer_allocator())
|
||||
{}
|
||||
|
||||
public:
|
||||
struct internal_type_t{};
|
||||
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
|
||||
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
|
||||
{}
|
||||
|
||||
public:
|
||||
scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
|
||||
{
|
||||
outer_allocator_type::operator=(other.outer_allocator());
|
||||
return *this;
|
||||
}
|
||||
|
||||
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
|
||||
{
|
||||
outer_allocator_type::operator=(boost::move(other.outer_allocator()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(scoped_allocator_adaptor_base &r)
|
||||
{
|
||||
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
|
||||
}
|
||||
|
||||
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
|
||||
{ l.swap(r); }
|
||||
|
||||
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); }
|
||||
|
||||
outer_allocator_type & outer_allocator()
|
||||
{ return static_cast<outer_allocator_type&>(*this); }
|
||||
|
||||
const outer_allocator_type &outer_allocator() const
|
||||
{ return static_cast<const outer_allocator_type&>(*this); }
|
||||
|
||||
scoped_allocator_type select_on_container_copy_construction() const
|
||||
{
|
||||
return scoped_allocator_type
|
||||
(internal_type_t()
|
||||
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
|
||||
//Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
|
||||
//as inner_allocator() is equal to *this and that would trigger an infinite loop
|
||||
, this->inner_allocator()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//Scoped allocator
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
||||
|
||||
//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
|
||||
//! The class template scoped_allocator_adaptor is an allocator template that specifies
|
||||
//! the memory resource (the outer allocator) to be used by a container (as any other
|
||||
//! allocator does) and also specifies an inner allocator resource to be passed to
|
||||
//! the constructor of every element within the container.
|
||||
//!
|
||||
//! This adaptor is
|
||||
//! instantiated with one outer and zero or more inner allocator types. If
|
||||
//! instantiated with only one allocator type, the inner allocator becomes the
|
||||
//! scoped_allocator_adaptor itself, thus using the same allocator resource for the
|
||||
//! container and every element within the container and, if the elements themselves
|
||||
//! are containers, each of their elements recursively. If instantiated with more than
|
||||
//! one allocator, the first allocator is the outer allocator for use by the container,
|
||||
//! the second allocator is passed to the constructors of the container's elements,
|
||||
//! and, if the elements themselves are containers, the third allocator is passed to
|
||||
//! the elements' elements, and so on. If containers are nested to a depth greater
|
||||
//! than the number of allocators, the last allocator is used repeatedly, as in the
|
||||
//! single-allocator case, for any remaining recursions.
|
||||
//!
|
||||
//! [<b>Note</b>: The
|
||||
//! scoped_allocator_adaptor is derived from the outer allocator type so it can be
|
||||
//! substituted for the outer allocator type in most expressions. -end note]
|
||||
//!
|
||||
//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
|
||||
//! an <code>outer_allocator()</code> member function and
|
||||
//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
|
||||
//! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
|
||||
//!
|
||||
//! [<b>Note</b>: <code>OUTERMOST(x)</code> and
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
|
||||
//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
|
||||
//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
|
||||
template <typename OuterAlloc, typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor
|
||||
|
||||
#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
||||
|
||||
template <typename OuterAlloc, typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
|
||||
|
||||
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template <typename OuterAlloc, BOOST_MOVE_CLASS9>
|
||||
class scoped_allocator_adaptor
|
||||
#endif
|
||||
|
||||
: public container_detail::scoped_allocator_adaptor_base
|
||||
<OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
|
||||
|
||||
public:
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef container_detail::scoped_allocator_adaptor_base
|
||||
<OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type;
|
||||
typedef typename base_type::internal_type_t internal_type_t;
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef OuterAlloc outer_allocator_type;
|
||||
//! Type: For exposition only
|
||||
//!
|
||||
typedef allocator_traits<OuterAlloc> outer_traits_type;
|
||||
//! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
|
||||
//! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
|
||||
typedef typename base_type::inner_allocator_type inner_allocator_type;
|
||||
typedef allocator_traits<inner_allocator_type> inner_traits_type;
|
||||
typedef typename outer_traits_type::value_type value_type;
|
||||
typedef typename outer_traits_type::size_type size_type;
|
||||
typedef typename outer_traits_type::difference_type difference_type;
|
||||
typedef typename outer_traits_type::pointer pointer;
|
||||
typedef typename outer_traits_type::const_pointer const_pointer;
|
||||
typedef typename outer_traits_type::void_pointer void_pointer;
|
||||
typedef typename outer_traits_type::const_void_pointer const_void_pointer;
|
||||
//! Type: A type with a constant boolean <code>value</code> == true if
|
||||
//!`allocator_traits<Allocator>:: propagate_on_container_copy_assignment::value` is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
|
||||
//! Type: A type with a constant boolean <code>value</code> == true if
|
||||
//!`allocator_traits<Allocator>:: propagate_on_container_move_assignment::value` is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_move_assignment propagate_on_container_move_assignment;
|
||||
|
||||
//! Type: A type with a constant boolean <code>value</code> == true if
|
||||
//! `allocator_traits<Allocator>:: propagate_on_container_swap::value` is
|
||||
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
||||
typedef typename base_type::
|
||||
propagate_on_container_swap propagate_on_container_swap;
|
||||
|
||||
//! Type: A type with a constant boolean <code>value</code> == true if
|
||||
//!`allocator_traits<Allocator>:: is_always_equal::value` is
|
||||
//! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
|
||||
typedef typename base_type::
|
||||
is_always_equal is_always_equal;
|
||||
|
||||
//! Type: Rebinds scoped allocator to
|
||||
//! <code>typedef scoped_allocator_adaptor
|
||||
//! < typename outer_traits_type::template portable_rebind_alloc<U>::type
|
||||
//! , InnerAllocs... ></code>
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef scoped_allocator_adaptor
|
||||
< typename outer_traits_type::template portable_rebind_alloc<U>::type
|
||||
, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other;
|
||||
};
|
||||
|
||||
//! <b>Effects</b>: value-initializes the OuterAlloc base class
|
||||
//! and the inner allocator object.
|
||||
scoped_allocator_adaptor()
|
||||
{}
|
||||
|
||||
~scoped_allocator_adaptor()
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: initializes each allocator within the adaptor with
|
||||
//! the corresponding allocator from other.
|
||||
scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
|
||||
: base_type(other.base())
|
||||
{}
|
||||
|
||||
//! <b>Effects</b>: move constructs each allocator within the adaptor with
|
||||
//! the corresponding allocator from other.
|
||||
scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
|
||||
: base_type(::boost::move(other.base()))
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
|
||||
//!
|
||||
//! <b>Effects</b>: initializes the OuterAlloc base class with boost::forward<OuterA2>(outerAlloc) and inner
|
||||
//! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the
|
||||
//! corresponding allocator from the argument list).
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
|
||||
: base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
|
||||
{}
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\
|
||||
template <class OuterA2>\
|
||||
scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\
|
||||
: base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\
|
||||
{}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE)
|
||||
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE
|
||||
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
|
||||
//!
|
||||
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
|
||||
: base_type(other.base())
|
||||
{}
|
||||
|
||||
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
|
||||
//!
|
||||
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator
|
||||
//! rvalue from other.
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor
|
||||
<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other)
|
||||
: base_type(::boost::move(other.base()))
|
||||
{}
|
||||
|
||||
scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
|
||||
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
|
||||
|
||||
scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
|
||||
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! <b>Effects</b>: swaps *this with r.
|
||||
//!
|
||||
void swap(scoped_allocator_adaptor &r);
|
||||
|
||||
//! <b>Effects</b>: swaps *this with r.
|
||||
//!
|
||||
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! <code>static_cast<OuterAlloc&>(*this)</code>.
|
||||
outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! <code>static_cast<const OuterAlloc&>(*this)</code>.
|
||||
const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
||||
inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
|
||||
inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
|
||||
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! <code>allocator_traits<OuterAlloc>:: max_size(outer_allocator())</code>.
|
||||
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return outer_traits_type::max_size(this->outer_allocator()); }
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! calls <code>OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p)</code>.
|
||||
template <class T>
|
||||
void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
|
||||
::destroy(get_outermost_allocator(this->outer_allocator()), p);
|
||||
}
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
|
||||
pointer allocate(size_type n)
|
||||
{ return outer_traits_type::allocate(this->outer_allocator(), n); }
|
||||
|
||||
//! <b>Returns</b>:
|
||||
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
|
||||
pointer allocate(size_type n, const_void_pointer hint)
|
||||
{ return outer_traits_type::allocate(this->outer_allocator(), n, hint); }
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
|
||||
void deallocate(pointer p, size_type n)
|
||||
{ outer_traits_type::deallocate(this->outer_allocator(), p, n); }
|
||||
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
//! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator
|
||||
//! Allocator in the adaptor is initialized from the result of calling
|
||||
//! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
|
||||
//! the corresponding allocator in *this.
|
||||
scoped_allocator_adaptor select_on_container_copy_construction() const;
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
base_type &base() { return *this; }
|
||||
|
||||
const base_type &base() const { return *this; }
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::
|
||||
//! construct(OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
|
||||
//!
|
||||
//! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
|
||||
//! <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>:: value</code> is true, calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, allocator_arg,
|
||||
//! inner_allocator(), std::forward<Args>(args)...)</code>.
|
||||
//!
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
|
||||
//! be implemented so that condition will be replaced by
|
||||
//! constructible_with_allocator_prefix<T>::value. -end note]
|
||||
//!
|
||||
//! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
|
||||
//! <code>is_constructible<T, Args..., inner_allocator_type>:: value</code> is true, calls
|
||||
//! <code>OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p,
|
||||
//! std::forward<Args>(args)..., inner_allocator())</code>.
|
||||
//!
|
||||
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
|
||||
//! implemented so that condition will be replaced by
|
||||
//! <code>constructible_with_allocator_suffix<T>:: value</code>. -end note]
|
||||
//!
|
||||
//! 4) Otherwise, the program is ill-formed.
|
||||
//!
|
||||
//! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
|
||||
//! to true but the specific constructor does not take an allocator. This definition prevents a silent
|
||||
//! failure to pass an inner allocator to a contained element. -end note]
|
||||
template < typename T, class ...Args>
|
||||
void construct(T* p, BOOST_FWD_REF(Args)...args)
|
||||
{
|
||||
container_detail::dispatch_uses_allocator
|
||||
( (get_outermost_allocator)(this->outer_allocator())
|
||||
, this->inner_allocator(), p, ::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//Disable this overload if the first argument is pair as some compilers have
|
||||
//overload selection problems when the first parameter is a pair.
|
||||
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
|
||||
template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
|
||||
void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
|
||||
{\
|
||||
container_detail::dispatch_uses_allocator\
|
||||
( (get_outermost_allocator)(this->outer_allocator())\
|
||||
, this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE)
|
||||
#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE
|
||||
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
//Internal function
|
||||
template <class OuterA2>
|
||||
scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
|
||||
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
|
||||
{}
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<bool ZeroInner>
|
||||
struct scoped_allocator_operator_equal
|
||||
{
|
||||
//Optimize equal outer allocator types with
|
||||
//allocator_traits::equal which uses is_always_equal
|
||||
template<class IA>
|
||||
static bool equal_outer(const IA &l, const IA &r)
|
||||
{ return allocator_traits<IA>::equal(l, r); }
|
||||
|
||||
//Otherwise compare it normally
|
||||
template<class IA1, class IA2>
|
||||
static bool equal_outer(const IA1 &l, const IA2 &r)
|
||||
{ return l == r; }
|
||||
|
||||
//Otherwise compare it normally
|
||||
template<class IA>
|
||||
static bool equal_inner(const IA &l, const IA &r)
|
||||
{ return allocator_traits<IA>::equal(l, r); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct scoped_allocator_operator_equal<true>
|
||||
: scoped_allocator_operator_equal<false>
|
||||
{
|
||||
//when inner allocator count is zero,
|
||||
//inner_allocator_type is the same as outer_allocator_type
|
||||
//so both types can be different in operator==
|
||||
template<class IA1, class IA2>
|
||||
static bool equal_inner(const IA1 &, const IA2 &)
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
|
||||
inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
|
||||
,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
|
||||
#else
|
||||
const bool has_zero_inner = boost::container::container_detail::is_same<P0, void>::value;
|
||||
#endif
|
||||
typedef scoped_allocator_operator_equal<has_zero_inner> equal_t;
|
||||
return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) &&
|
||||
equal_t::equal_inner(a.inner_allocator(), b.inner_allocator());
|
||||
}
|
||||
|
||||
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
|
||||
inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
|
||||
,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
|
||||
{ return !(a == b); }
|
||||
|
||||
}} // namespace boost { namespace container {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
|
||||
@@ -0,0 +1,71 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_FWD_HPP
|
||||
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares boost::container::scoped_allocator_adaptor
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
#include <boost/container/uses_allocator_fwd.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
||||
|
||||
template <typename OuterAlloc, typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor;
|
||||
|
||||
#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
||||
|
||||
template <typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor;
|
||||
|
||||
template <typename OuterAlloc, typename ...InnerAllocs>
|
||||
class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
|
||||
|
||||
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template <typename OuterAlloc, BOOST_MOVE_CLASSDFLT9>
|
||||
class scoped_allocator_adaptor;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else //BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
}} // namespace boost { namespace container {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,171 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. 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_THROW_EXCEPTION_HPP
|
||||
#define BOOST_CONTAINER_THROW_EXCEPTION_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
# include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <stdexcept> //for std exception types
|
||||
#include <string> //for implicit std::string conversion
|
||||
#include <new> //for std::bad_alloc
|
||||
#else
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdlib> //for std::abort
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS)
|
||||
//The user must provide definitions for the following functions
|
||||
|
||||
void throw_bad_alloc();
|
||||
|
||||
void throw_out_of_range(const char* str);
|
||||
|
||||
void throw_length_error(const char* str);
|
||||
|
||||
void throw_logic_error(const char* str);
|
||||
|
||||
void throw_runtime_error(const char* str);
|
||||
|
||||
#elif defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
inline void throw_bad_alloc()
|
||||
{
|
||||
BOOST_ASSERT(!"boost::container bad_alloc thrown");
|
||||
std::abort();
|
||||
}
|
||||
|
||||
inline void throw_out_of_range(const char* str)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
inline void throw_length_error(const char* str)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!"boost::container length_error thrown", str);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
inline void throw_logic_error(const char* str)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
inline void throw_runtime_error(const char* str)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
#else //defined(BOOST_NO_EXCEPTIONS)
|
||||
|
||||
//! Exception callback called by Boost.Container when fails to allocate the requested storage space.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::bad_alloc()</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_bad_alloc()
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal arguments out of range.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::out_of_range(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_out_of_range(const char* str)
|
||||
{
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal errors resizing.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::length_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_length_error(const char* str)
|
||||
{
|
||||
throw std::length_error(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors in the internal logical
|
||||
//! of the program, such as violation of logical preconditions or class invariants.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::logic_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_logic_error(const char* str)
|
||||
{
|
||||
throw std::logic_error(str);
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
|
||||
//! <ul>
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::runtime_error(str)</code> is thrown.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
||||
//!
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
||||
//! </ul>
|
||||
inline void throw_runtime_error(const char* str)
|
||||
{
|
||||
throw std::runtime_error(str);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}} //namespace boost { namespace container {
|
||||
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
|
||||
@@ -0,0 +1,169 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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_USES_ALLOCATOR_HPP
|
||||
#define BOOST_CONTAINER_USES_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/container/uses_allocator_fwd.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed
|
||||
//! with an allocator as its last constructor argument. Ideally, all constructors of T (including the
|
||||
//! copy and move constructors) should have a variant that accepts a final argument of
|
||||
//! allocator_type.
|
||||
//!
|
||||
//! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type,
|
||||
//! allocator_type and at least one constructor for which allocator_type is the last
|
||||
//! parameter. If not all constructors of T can be called with a final allocator_type argument,
|
||||
//! and if T is used in a context where a container must call such a constructor, then the program is
|
||||
//! ill-formed.
|
||||
//!
|
||||
//! <code>
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! class Z {
|
||||
//! public:
|
||||
//! typedef Allocator allocator_type;
|
||||
//!
|
||||
//! // Default constructor with optional allocator suffix
|
||||
//! Z(const allocator_type& a = allocator_type());
|
||||
//!
|
||||
//! // Copy constructor and allocator-extended copy constructor
|
||||
//! Z(const Z& zz);
|
||||
//! Z(const Z& zz, const allocator_type& a);
|
||||
//! };
|
||||
//!
|
||||
//! // Specialize trait for class template Z
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! struct constructible_with_allocator_suffix<Z<T,Allocator> >
|
||||
//! { static const bool value = true; };
|
||||
//! </code>
|
||||
//!
|
||||
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)"
|
||||
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
||||
//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
|
||||
//! Applications aiming portability with several compilers should always define this trait.
|
||||
//!
|
||||
//! In conforming C++11 compilers or compilers supporting SFINAE expressions
|
||||
//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
|
||||
//! to detect if a type should be constructed with suffix or prefix allocator arguments.
|
||||
template <class T>
|
||||
struct constructible_with_allocator_suffix
|
||||
{ static const bool value = false; };
|
||||
|
||||
//! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed
|
||||
//! with allocator_arg and T::allocator_type as its first two constructor arguments.
|
||||
//! Ideally, all constructors of T (including the copy and move constructors) should have a variant
|
||||
//! that accepts these two initial arguments.
|
||||
//!
|
||||
//! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type,
|
||||
//! allocator_type and at least one constructor for which allocator_arg_t is the first
|
||||
//! parameter and allocator_type is the second parameter. If not all constructors of T can be
|
||||
//! called with these initial arguments, and if T is used in a context where a container must call such
|
||||
//! a constructor, then the program is ill-formed.
|
||||
//!
|
||||
//! <code>
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! class Y {
|
||||
//! public:
|
||||
//! typedef Allocator allocator_type;
|
||||
//!
|
||||
//! // Default constructor with and allocator-extended default constructor
|
||||
//! Y();
|
||||
//! Y(allocator_arg_t, const allocator_type& a);
|
||||
//!
|
||||
//! // Copy constructor and allocator-extended copy constructor
|
||||
//! Y(const Y& yy);
|
||||
//! Y(allocator_arg_t, const allocator_type& a, const Y& yy);
|
||||
//!
|
||||
//! // Variadic constructor and allocator-extended variadic constructor
|
||||
//! template<class ...Args> Y(Args&& args...);
|
||||
//! template<class ...Args>
|
||||
//! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args);
|
||||
//! };
|
||||
//!
|
||||
//! // Specialize trait for class template Y
|
||||
//! template <class T, class Allocator = allocator<T> >
|
||||
//! struct constructible_with_allocator_prefix<Y<T,Allocator> >
|
||||
//! { static const bool value = true; };
|
||||
//!
|
||||
//! </code>
|
||||
//!
|
||||
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
|
||||
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
|
||||
//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
|
||||
//! Applications aiming portability with several compilers should always define this trait.
|
||||
//!
|
||||
//! In conforming C++11 compilers or compilers supporting SFINAE expressions
|
||||
//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used
|
||||
//! to detect if a type should be constructed with suffix or prefix allocator arguments.
|
||||
template <class T>
|
||||
struct constructible_with_allocator_prefix
|
||||
{ static const bool value = false; };
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
namespace container_detail {
|
||||
|
||||
template<typename T, typename Allocator>
|
||||
struct uses_allocator_imp
|
||||
{
|
||||
// Use SFINAE (Substitution Failure Is Not An Error) to detect the
|
||||
// presence of an 'allocator_type' nested type convertilble from Allocator.
|
||||
private:
|
||||
typedef char yes_type;
|
||||
struct no_type{ char dummy[2]; };
|
||||
|
||||
// Match this function if T::allocator_type exists and is
|
||||
// implicitly convertible from Allocator
|
||||
template <class U>
|
||||
static yes_type test(typename U::allocator_type);
|
||||
|
||||
// Match this function if T::allocator_type exists and it's type is `erased_type`.
|
||||
template <class U, class V>
|
||||
static typename container_detail::enable_if
|
||||
< container_detail::is_same<typename U::allocator_type, erased_type>
|
||||
, yes_type
|
||||
>::type test(const V&);
|
||||
|
||||
// Match this function if TypeT::allocator_type does not exist or is
|
||||
// not convertible from Allocator.
|
||||
template <typename U>
|
||||
static no_type test(...);
|
||||
static Allocator alloc; // Declared but not defined
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(alloc)) == sizeof(yes_type);
|
||||
};
|
||||
|
||||
} //namespace container_detail {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Remark</b>: Automatically detects whether T has a nested allocator_type that is convertible from
|
||||
//! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
|
||||
//! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not
|
||||
//! have a nested allocator_type but is nonetheless constructible using the specified Allocator where either:
|
||||
//! the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or
|
||||
//! the last argument of a constructor has type Alloc.
|
||||
//!
|
||||
//! <b>Result</b>: uses_allocator<T, Allocator>::value== true if a type T::allocator_type
|
||||
//! exists and either is_convertible<Alloc, T::allocator_type>::value != false or T::allocator_type
|
||||
//! is an alias `erased_type`. False otherwise.
|
||||
template <typename T, typename Allocator>
|
||||
struct uses_allocator
|
||||
: container_detail::uses_allocator_imp<T, Allocator>
|
||||
{};
|
||||
|
||||
}} //namespace boost::container
|
||||
|
||||
#endif //BOOST_CONTAINER_USES_ALLOCATOR_HPP
|
||||
@@ -0,0 +1,73 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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_USES_ALLOCATOR_FWD_HPP
|
||||
#define BOOST_CONTAINER_USES_ALLOCATOR_FWD_HPP
|
||||
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
||||
|
||||
//! \file
|
||||
//! This header forward declares boost::container::constructible_with_allocator_prefix,
|
||||
//! boost::container::constructible_with_allocator_suffix and
|
||||
//! boost::container::uses_allocator. Also defines the following types:
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template <int Dummy = 0>
|
||||
struct std_allocator_arg_holder
|
||||
{
|
||||
static ::std::allocator_arg_t *dummy;
|
||||
};
|
||||
|
||||
template <int Dummy> //Silence null-reference compiler warnings
|
||||
::std::allocator_arg_t *std_allocator_arg_holder<Dummy>::dummy = reinterpret_cast< ::std::allocator_arg_t * >(0x1234);
|
||||
|
||||
typedef const std::allocator_arg_t & allocator_arg_t;
|
||||
|
||||
#else
|
||||
|
||||
//! The allocator_arg_t struct is an empty structure type used as a unique type to
|
||||
//! disambiguate constructor and function overloading. Specifically, several types
|
||||
//! have constructors with allocator_arg_t as the first argument, immediately followed
|
||||
//! by an argument of a type that satisfies Allocator requirements
|
||||
typedef unspecified allocator_arg_t;
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
//! The `erased_type` struct is an empty struct that serves as a placeholder for a type
|
||||
//! T in situations where the actual type T is determined at runtime. For example,
|
||||
//! the nested type, `allocator_type`, is an alias for `erased_type` in classes that
|
||||
//! use type-erased allocators.
|
||||
struct erased_type {};
|
||||
|
||||
//! A instance of type
|
||||
//! allocator_arg_t
|
||||
static allocator_arg_t allocator_arg = BOOST_CONTAINER_DOC1ST(unspecified, *std_allocator_arg_holder<>::dummy);
|
||||
|
||||
// @cond
|
||||
|
||||
template <class T>
|
||||
struct constructible_with_allocator_suffix;
|
||||
|
||||
template <class T>
|
||||
struct constructible_with_allocator_prefix;
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
struct uses_allocator;
|
||||
|
||||
// @endcond
|
||||
|
||||
}} // namespace boost { namespace container {
|
||||
|
||||
#endif //BOOST_CONTAINER_USES_ALLOCATOR_HPP
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user