New upstream version 8.1.0

This commit is contained in:
geos_one
2025-08-10 01:34:16 +02:00
commit c891bb7105
4398 changed files with 838833 additions and 0 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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>
inline T* addressof(T& obj)
{
return static_cast<T*>(
static_cast<void*>(
const_cast<char*>(
&reinterpret_cast<const char&>(obj)
)));
}
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP

View File

@@ -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<int ...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<int ...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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -0,0 +1,293 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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
, 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
, 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
, 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
, 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)); }
//template <typename ConstructAlloc, typename ArgAlloc, class Pair, class Pair2>
//void dispatch_uses_allocator( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc
// , pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
} //namespace container_detail
}} // namespace boost { namespace container {
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,828 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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/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); }
//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;
template<class Allocator>
void construct_in_place(Allocator &a, T* ptr)
{ (*m_pe)(a, ptr); }
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>
void operator()(Allocator &a, T *ptr)
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
template<class Allocator, class T, int ...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_))...);
}
container_detail::tuple<Args&...> args_;
};
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#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); }\
\
BOOST_MOVE_MREF##N\
};\
//
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()
{}
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

View File

@@ -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

View File

@@ -0,0 +1,87 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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 Pair>
struct select1st
{
typedef Pair argument_type;
typedef typename Pair::first_type result_type;
template<class OtherPair>
const typename Pair::first_type& operator()(const OtherPair& x) const
{ return x.first; }
const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
{ return x; }
};
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP

View File

@@ -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

View File

@@ -0,0 +1,337 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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>
#include <boost/move/adl_move_swap.hpp> //swap
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/move/utility_core.hpp>
namespace boost {
namespace container {
namespace container_detail {
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 <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))
{}
//piecewise_construct missing
//template <class U, class V> pair(pair<U, V>&& p);
//template <class... Args1, class... Args2>
// pair(piecewise_construct_t, tuple<Args1...> first_args,
// tuple<Args2...> second_args);
//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 {
//Without this specialization recursive flat_(multi)map instantiation fails
//because is_enum needs to instantiate the recursive pair, leading to a compilation error).
//This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
template<class T>
struct is_enum;
template<class T, class U>
struct is_enum< ::boost::container::container_detail::pair<T, U> >
{
static const bool value = false;
};
template <class T>
struct is_class;
//This specialization is needed to avoid instantiation of pair in
//is_class, and allow recursive maps.
template <class T1, class T2>
struct is_class< ::boost::container::container_detail::pair<T1, T2> >
{
static const bool value = true;
};
#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;
};
} //namespace move_detail{
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,49 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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 m_t;
};
} //namespace container_detail {
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP

View File

@@ -0,0 +1,158 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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/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() { }
// implicit copy-constructor is okay
// Construct tuple from separate arguments.
tuple(typename add_const_reference<Head>::type v,
typename add_const_reference<Tail>::type... vtail)
: inherited(vtail...), m_head(v)
{}
// 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&&...> tie_forward(Values&&... values)
{ return tuple<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<int... Indexes>
struct index_tuple{};
template<std::size_t Num, typename Tuple = index_tuple<> >
struct build_number_seq;
template<std::size_t Num, int... Indexes>
struct build_number_seq<Num, index_tuple<Indexes...> >
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
{};
template<int... Indexes>
struct build_number_seq<0, index_tuple<Indexes...> >
{ typedef index_tuple<Indexes...> type; };
}}} //namespace boost { namespace container { namespace container_detail {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP

View File

@@ -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

View File

@@ -0,0 +1,92 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_FALLTHOUGH)
#define BOOST_CONTAINER_FALLTHOUGH
#else
#define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH;
#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
#else
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
#endif
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP

View File

@@ -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_ALLOCATOR_HPP

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>
::std::allocator_arg_t *std_allocator_arg_holder<Dummy>::dummy;
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